簡體   English   中英

無法使用 Ionic.Zip 創建 zip 文件

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

我不確定我在哪里做錯了什么,但是我使用 DotNetZip 庫創建的 zip 正在創建一個內容為空白的 zip 文件。 或者 zip 中的文件大小顯示為 0Kb 並且無法打開。

代碼:

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));
        }
    }
}

您的代碼至少有兩個問題:

  1. 讀取的 stream 完全由await responseStream.CopyToAsync(stream)消耗。 您可以倒帶 responseStream 來解決這個問題,但是將數據保存到 memory stream 是完全沒用的。

  2. 響應zip.Save在調用 zip.Save 之前處理。

你可以做什么:保持流打開,直到調用 Save 並在之后處理它們。 正如 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();
    }
}

文檔有一些關於如何使它變得更智能的提示。

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