【问题标题】:Using a generic stream to create a zipped file with SharpCompress使用通用流通过 SharpCompress 创建压缩文件
【发布时间】:2017-06-01 10:44:45
【问题描述】:

由于 System.IO.Compression seems to be out of reach for now 如果我想同时使用 dotnet core + net461,我已经尝试使用 SharpCompress

“读取 zip”部分很简单,但我很难找出如何写入 zip 流。

The wiki of the project 有点过时了。 This is the only example 我发现它适用于写入流。我试图遵循它并使其适应我的需求,但我被它抛出的异常困住了:

using Microsoft.VisualStudio.TestTools.UnitTesting;
using SharpCompress.Common;
using SharpCompress.Compressors.Deflate;
using SharpCompress.Writers;
using System;
using System.IO;

namespace DbManager.DjdbCore.Tests
{
    [TestClass]
    public class ZipTests
    {
        public ZipTests()
        {
            Directory.SetCurrentDirectory(AppContext.BaseDirectory);
        }

        [TestMethod]
        public void Test()
        {            
            var zip = File.OpenWrite(@"..\..\..\..\..\test-resources\zip_file_test.zip");
            var writerOptions = new WriterOptions(CompressionType.Deflate);
            var zipWriter = WriterFactory.Open(zip, ArchiveType.Zip, writerOptions);            

            var memoryStream = new MemoryStream();            
            var binaryWriter = new BinaryWriter(memoryStream);
            binaryWriter.Write("Test string inside binary file - text to fill it up: qoiwjqefñlawijfñlaskdjfioqwjefñalskvndñaskvnqo`wiefowainvñaslkfjnwpowiqjfeopwiqjnfjñlaskdjfñlasdfjiowiqjefñaslkdjfñalskjfpqwoiefjqw");

            var deflateStream = new DeflateStream(memoryStream, SharpCompress.Compressors.CompressionMode.Compress);
            deflateStream.Write(memoryStream.ToArray(), 0, Convert.ToInt32(memoryStream.Length));

            // EXCEPTION: SharpCompress.Compressors.Deflate.ZlibException: 'Cannot Read after Writing.'
            // Source code: if (_streamMode != StreamMode.Reader) { throw new ZlibException("Cannot Read after Writing."); }
            zipWriter.Write("test_file_inside_zip.bin", deflateStream, DateTime.Now);                         

            zip.Flush();

            zipWriter.Dispose();
            zip.Dispose();            
        }

    }
}

如果有帮助,这就是我使用库 System.IO.Compression 使用的(并且它有效,但仅在 dotnet 核心中):

private void WriteAsZipBinary()
{
    //Open the zip file if it exists, else create a new one 
    var zip = ZipPackage.Open(this.FileFullPath, FileMode.OpenOrCreate, FileAccess.ReadWrite);

    var zipStream = ZipManager.GetZipWriteStream(zip, nameOfFileInsideZip);

    var memoryStream = new MemoryStream();
    var binaryWriter = new BinaryWriter(memoryStream);

    // Here is where strings etc are written to the binary file:
    WriteStuffInBinaryStream(ref binaryWriter);

    //Read all of the bytes from the file to add to the zip file 
    byte[] bites = new byte[Convert.ToInt32(memoryStream.Length - 1) + 1];
    memoryStream.Position = 0;
    memoryStream.Read(bites, 0, Convert.ToInt32(memoryStream.Length));

    binaryWriter.Dispose();
    binaryWriter = null;

    memoryStream.Dispose();
    memoryStream = null;

    zipStream.Position = 0;
    zipStream.Write(bites, 0, bites.Length);

    zip.Close();

}   

public static Stream GetZipWriteStream(Package zip, string renamedFileName)
{

    //Replace spaces with an underscore (_) 
    string uriFileName = renamedFileName.Replace(" ", "_");

    //A Uri always starts with a forward slash "/" 
    string zipUri = string.Concat("/", Path.GetFileName(uriFileName));

    Uri partUri = new Uri(zipUri, UriKind.Relative);
    string contentType = "Zip"; // System.Net.Mime.MediaTypeNames.Application.Zip;

    //The PackagePart contains the information: 
    // Where to extract the file when it's extracted (partUri) 
    // The type of content stream (MIME type):  (contentType) 
    // The type of compression:  (CompressionOption.Normal)   
    PackagePart pkgPart = zip.CreatePart(partUri, contentType, CompressionOption.Normal);

    //Compress and write the bytes to the zip file 
    return pkgPart.GetStream();

}

【问题讨论】:

    标签: c# .net-core sharpcompress


    【解决方案1】:

    我将在这里发布来自@adamhathcock(项目所有者)的answer on github

    [TestMethod]
    public void Test()
    {            
    
        var writerOptions = new WriterOptions(CompressionType.Deflate);
        using(var zip = File.OpenWrite(@"..\..\..\..\..\test-resources\zip_file_test.zip"))
        using(var zipWriter = WriterFactory.Open(zip, ArchiveType.Zip, writerOptions))
        {
            var memoryStream = new MemoryStream();            
            var binaryWriter = new BinaryWriter(memoryStream);
            binaryWriter.Write("Test string inside binary file - text to fill it up: qoiwjqefñlawijfñlaskdjfioqwjefñalskvndñaskvnqo`wiefowainvñaslkfjnwpowiqjfeopwiqjnfjñlaskdjfñlasdfjiowiqjefñaslkdjfñalskjfpqwoiefjqw");
    
            memoryStream.Position = 0;
            zipWriter.Write("test_file_inside_zip.bin", memoryStream, DateTime.Now);                          
        }
    }
    

    两件事:

    1. 写入后忘记重置 MemoryStream 以便读取。

    2. 您无需手动使用 DeflateStream。您已经告诉 ZipWriter 使用什么压缩。如果它有效,您将双重压缩实际上是垃圾的字节。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多