简体   繁体   English

无法使用 Ionic.Zip 创建 zip 文件

[英]Unable to create zip file using Ionic.Zip

I'm not sure where and what am I doing wrong, but the zip that I'm creating using DotNetZip library, is creating a zip file whose contents are blank.我不确定我在哪里做错了什么,但是我使用 DotNetZip 库创建的 zip 正在创建一个内容为空白的 zip 文件。 Or the size of file in zip is showing as 0Kb and unable to open it.或者 zip 中的文件大小显示为 0Kb 并且无法打开。

Code:代码:

public static async Task DotNetZipFileAsync(MemoryStream stream, string bucket, List<List<string>> pdfFileSet, IAmazonS3 s3Client)
        {
           
            using Ionic.Zip.ZipFile zip = new ZipFile();
            foreach (var pdfFile in pdfFileSet)
            {
                foreach (var file in pdfFile)
                {
                    GetObjectRequest request = new GetObjectRequest
                    {
                        BucketName = bucket,
                        Key = file
                    };
                    
                    using GetObjectResponse response = await s3Client.GetObjectAsync(request);
                    using Stream responseStream = response.ResponseStream;
                    ZipEntry zipEntry = zip.AddEntry(file.Split('/')[^1], responseStream);
                    await responseStream.CopyToAsync(stream);
                }
            }
            zip.Save(stream);
            stream.Seek(0,SeekOrigin.Begin);
            await stream.CopyToAsync(new FileStream(@"C:\LocalRepo\Temp.zip", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite));
        }
    }
}

Your code has at least two problems:您的代码至少有两个问题:

  1. The read stream is completely consumed by the await responseStream.CopyToAsync(stream) .读取的 stream 完全由await responseStream.CopyToAsync(stream)消耗。 You could rewind the responseStream to cope with this, but saving the data into the memory stream is completely useless.您可以倒带 responseStream 来解决这个问题,但是将数据保存到 memory stream 是完全没用的。

  2. The response stream is disposed before zip.Save is called.响应zip.Save在调用 zip.Save 之前处理。

What you could do: keep the streams open until Save is called and dispose them afterwards.你可以做什么:保持流打开,直到调用 Save 并在之后处理它们。 As Alexey Rumyantsev discovered (see comments), also the GetObjectResponse objects need to be kept until the ZIP file is saved.正如 Alexey Rumyantsev 发现的(见评论), GetObjectResponse对象也需要保留,直到 ZIP 文件被保存。

using Ionic.Zip.ZipFile zip = new ZipFile();
var disposables = List<IDisposable>();
try
{
    foreach (var pdfFile in pdfFileSet)
    {
        foreach (var file in pdfFile)
        {
            GetObjectRequest request = new GetObjectRequest
            {
                BucketName = bucket,
                Key = file
            };
            
            var response = await s3Client.GetObjectAsync(request);
            disposables.Add(response);
            var responseStream = response.ResponseStream;
            disposables.Add(responseStream);
            ZipEntry zipEntry = zip.AddEntry(file.Split('/')[^1], responseStream);
        }
    }
    using var fileStream = new FileStream(@"C:\LocalRepo\Temp.zip", FileMode.Create, FileAccess.Write);        
    zip.Save(fileStream);
}
finally
{
    foreach (var disposable in disposables)
    {
        disposable.Dispose();
    }
}

The documentation has some hints ony how this could be made smarter.文档有一些关于如何使它变得更智能的提示。

public static async Task DotNetZipFileAsync(string bucket, List<List<string>> pdfFileSet, IAmazonS3 s3Client)
{
    int read;
    using Ionic.Zip.ZipFile zip = new ZipFile();
    byte[] buffer = new byte[16 * 1024];
    
    foreach (var pdfFile in pdfFileSet)
    {
        foreach (var file in pdfFile)
        {
            GetObjectRequest request = new GetObjectRequest
            {
                BucketName = bucket,
                Key = file
            };

            using GetObjectResponse response = await s3Client.GetObjectAsync(request);
            using Stream responseStream = response.ResponseStream;
            using (MemoryStream ms = new MemoryStream())
            {
                while ((read = responseStream.Read(buffer, 0, buffer.Length)) > 0)
                {
                    ms.Write(buffer, 0, read);
                }
                zip.AddEntry(file.Split('/')[^1], ms.ToArray());
            }
        }
    }
    using var fileStream = new FileStream(@"C:\LocalRepo\Temp.zip", FileMode.Create, FileAccess.Write);
    zip.Save(fileStream);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM