c# - 使用 ZipOutputStream 归档多个文件给我一个空的归档文件

标签 c# .net memorystream sharpziplib

我正在尝试下载一堆我通过 ZipoutputStream 压缩(归档)的文件。

using (var zipStream = new ZipOutputStream(outputMemStream))
{
    foreach (var documentIdString in documentUniqueIdentifiers)
    {   
        ...
        var blockBlob = container.GetBlockBlobReference(documentId.ToString());

        var fileMemoryStream = new MemoryStream();

        blockBlob.DownloadToStream(fileMemoryStream);

        zipStream.SetLevel(3); 

        fileMemoryStream.Position = 0;

        ZipEntry newEntry = new ZipEntry(document.FileName);
        newEntry.DateTime = DateTime.Now;

        zipStream.PutNextEntry(newEntry);

        fileMemoryStream.Seek(0, SeekOrigin.Begin);
        StreamUtils.Copy(fileMemoryStream, zipStream, new byte[4096]);

        zipStream.IsStreamOwner = false; // False stops the Close also Closing the underlying stream.

    }

    outputMemStream.Seek(0, SeekOrigin.Begin);
    return outputMemStream;
}

在我的 Controller 中,我返回以下代码,该代码应该下载我在上一个示例中创建的 Zip 文件。 Controller 操作按照浏览器中应有的方式下载文件,但存档文件为空。我可以看到从上面的方法返回填充的内容长度...

file.Seek(0, SeekOrigin.Begin);
return File(file, "application/octet-stream", "Archive.zip");

有人知道为什么我的 Controller 返回的文件是空的或损坏的吗?

最佳答案

我相信您需要关闭您的条目和最终的 zip 流。您还应该使用并处置所有流。试试这个:

using (var zipStream = new ZipOutputStream(outputMemStream))
{
    zipStream.IsStreamOwner = false;
    // Set compression level
    zipStream.SetLevel(3); 

    foreach (var documentIdString in documentUniqueIdentifiers)
    {   
        ...
        var blockBlob = container.GetBlockBlobReference(documentId.ToString());

        using (var fileMemoryStream = new MemoryStream())
        {
            // Populate stream with bytes
            blockBlob.DownloadToStream(fileMemoryStream);

            // Create zip entry and set date
            ZipEntry newEntry = new ZipEntry(document.FileName);
            newEntry.DateTime = DateTime.Now;
            // Put entry RECORD, not actual data
            zipStream.PutNextEntry(newEntry);
            // Copy data to zip RECORD
            StreamUtils.Copy(fileMemoryStream, zipStream, new byte[4096]);
            // Mark this RECORD closed in the zip
            zipStream.CloseEntry();
        }
    }

    // Close the zip stream, parent stays open due to !IsStreamOwner
    zipStream.Close();

    outputMemStream.Seek(0, SeekOrigin.Begin);
    return outputMemStream;
}

编辑 - 您应该删除:

// Reset position of stream
fileMemoryStream.Position = 0;

很确定这就是问题所在。

关于c# - 使用 ZipOutputStream 归档多个文件给我一个空的归档文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29242261/

相关文章:

c# - 摆脱字符串中的扩展 ASCII 字符

.net - MEF:CompositionContainer 和部件生命周期和所有权

c# - 如何合并两个内存流?

C# 泛型类型转换 Decimal 到 Float - "Cannot convert type ' T1 ?' to ' T 2'"

c# - Visual Studio的Windows Style中的图标的图标路径在哪里

c# - 使用事件在 NHibernate 中进行数据审计

c# - 传入 CSV Excel 工作表的选项卡名称

c# - 无法读取超过流的末尾

c# - 如何用 0xFF 字节填充 MemoryStream?

c# - 什么是检索一周至今计算值的算法