Unzip a memorystream (Contains the zip file) and get the files

后端 未结 4 499
予麋鹿
予麋鹿 2020-11-27 16:31

I have a memory stream that contains a zip file in byte[] format .

Is there any way I can unzip this memory stream, without any need of writing the file to disk ?

4条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2020-11-27 17:06

    Yes, Change from using FastZip To new ZipFile(stream), but this only works if your stream can seek. (Just use your MemoryStream in new ZipFile(fs); instead of reading a file stream like the example.)

    C#
    using ICSharpCode.SharpZipLib.Core;
    using ICSharpCode.SharpZipLib.Zip;
    
    public void ExtractZipFile(string archiveFilenameIn, string password, string outFolder) {
        ZipFile zf = null;
        try {
            FileStream fs = File.OpenRead(archiveFilenameIn);
            zf = new ZipFile(fs);
            if (!String.IsNullOrEmpty(password)) {
                zf.Password = password;     // AES encrypted entries are handled automatically
            }
            foreach (ZipEntry zipEntry in zf) {
                if (!zipEntry.IsFile) {
                    continue;           // Ignore directories
                }
                String entryFileName = zipEntry.Name;
                // to remove the folder from the entry:- entryFileName = Path.GetFileName(entryFileName);
                // Optionally match entrynames against a selection list here to skip as desired.
                // The unpacked length is available in the zipEntry.Size property.
    
                byte[] buffer = new byte[4096];     // 4K is optimum
                Stream zipStream = zf.GetInputStream(zipEntry);
    
                // Manipulate the output filename here as desired.
                String fullZipToPath = Path.Combine(outFolder, entryFileName);
                string directoryName = Path.GetDirectoryName(fullZipToPath);
                if (directoryName.Length > 0)
                    Directory.CreateDirectory(directoryName);
    
                // Unzip file in buffered chunks. This is just as fast as unpacking to a buffer the full size
                // of the file, but does not waste memory.
                // The "using" will close the stream even if an exception occurs.
                using (FileStream streamWriter = File.Create(fullZipToPath)) {
                    StreamUtils.Copy(zipStream, streamWriter, buffer);
                }
            }
        } finally {
            if (zf != null) {
                zf.IsStreamOwner = true; // Makes close also shut the underlying stream
                zf.Close(); // Ensure we release resources
            }
        }
    }
    

    If you are using a non-seekable stream use ZipInputStream.

    // Calling example:
        WebClient webClient = new WebClient();
        Stream data = webClient.OpenRead("http://www.example.com/test.zip");
        // This stream cannot be opened with the ZipFile class because CanSeek is false.
        UnzipFromStream(data, @"c:\temp");
    
    public void UnzipFromStream(Stream zipStream, string outFolder) {
    
        ZipInputStream zipInputStream = new ZipInputStream(zipStream);
        ZipEntry zipEntry = zipInputStream.GetNextEntry();
        while (zipEntry != null) {
            String entryFileName = zipEntry.Name;
            // to remove the folder from the entry:- entryFileName = Path.GetFileName(entryFileName);
            // Optionally match entrynames against a selection list here to skip as desired.
            // The unpacked length is available in the zipEntry.Size property.
    
            byte[] buffer = new byte[4096];     // 4K is optimum
    
            // Manipulate the output filename here as desired.
            String fullZipToPath = Path.Combine(outFolder, entryFileName);
            string directoryName = Path.GetDirectoryName(fullZipToPath);
            if (directoryName.Length > 0)
                Directory.CreateDirectory(directoryName);
    
            // Unzip file in buffered chunks. This is just as fast as unpacking to a buffer the full size
            // of the file, but does not waste memory.
            // The "using" will close the stream even if an exception occurs.
            using (FileStream streamWriter = File.Create(fullZipToPath)) {
                StreamUtils.Copy(zipInputStream, streamWriter, buffer);
            }
            zipEntry = zipInputStream.GetNextEntry();
        }
    }
    

    Examples taken from the ICSharpCode Wiki

提交回复
热议问题