【问题标题】:How to recreate a Zip File from a MemoryStream如何从 MemoryStream 重新创建 Zip 文件
【发布时间】:2015-09-11 00:15:10
【问题描述】:

我四处寻找解决问题的方法,但似乎没有人瞄准我想要实现的目标。

我的问题是这样的,我将 Zip 文件存储在 Azure Blob 存储中,现在为了安全起见,我们有一个 API2 控制器操作来配置这些 zip 文件,而不是允许直接下载。此操作将检索 blob,并将其下载到流中,以便可以将其打包在 HTTPResponseMessage 中。

以上所有方法都有效,但是,当我尝试重新创建 zip 文件时,我被告知它已损坏。现在我只是试图让服务器(在 localhost 上运行)创建 zip 文件,而最终目标是让远程客户端应用程序执行此操作(我相当确定我在服务器上的问题的解决方案是相同的.

public class FileActionResult : IHttpActionResult 
{
  private HttpRequestMessage _request;
  private ICloudBlob _blob;

  public FileActionResult(HttpRequestMessage request, ICloudBlob blob)
  {
    _request = request;
    _blob = blob;
  }

  public async Task<HttpResponseMessage> ExecuteAsync(System.Threading.CancellationToken cancellationToken)
  {
    var fileStream = new MemoryStream();
    await _blob.DownloadToStreamAsync(fileStream);

    var byteTest = new byte[fileStream.Length];
    var test = fileStream.Read(byteTest, 0, (int)fileStream.Length);

    try
    {
      File.WriteAllBytes(@"C:\testPlatFiles\test.zip", byteTest);
    }
    catch(ArgumentException ex)
    {
      var a = ex;
    }

    var response = _request.CreateResponse(HttpStatusCode.Accepted);
    response.Content = new StreamContent(fileStream);
    response.Content.Headers.ContentLength = _blob.Properties.Length;
    response.Content.Headers.ContentType = new MediaTypeHeaderValue(_blob.Properties.ContentType);
    //set the fileName
    response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
    {
      FileName = _blob.Name,
      Size = _blob.Properties.Length
    };
    return response;  
  }
}

我查看了 Zip 库,看看是否存在将 zip 流转换回 zip 文件的解决方案,但我能找到的只是将 zip 文件读入流,或创建以提供文件下载而不是文件创建。

任何帮助将不胜感激,谢谢。

【问题讨论】:

  • 它是否取决于 zip 文件的大小?如果您尝试使用小于 1 Mb 的小 zip 文件,您还有问题吗?你也可以尝试做 fileStream.ToArray() 它会给你一个 byte[] arryay 与你的流的内容。
  • @AlexShapovalov 好的,所以 .ToArray() 对我有用,基本上我的问题是 filestream.Read 工作不正常,它写入了正确的字节数,但它们的值都是0. ToArray() 创建相同大小的 Byte 数组,但字节实际上有值。我的下一个问题是,在我的客户端上,流是 WebConnectionStream,因此将其转换为 MemoryStream 可能会更麻烦,但我现在就开始吧! :)

标签: c# azure zip azure-blob-storage memorystream


【解决方案1】:

您使用DotNetZip。它的ZipFile 类有一个静态工厂方法,可以做你想做的事:ZipFile.Read( Stream zipStream ) 将给定的流作为 zip 文件读取,并返回一个 ZipFile 实例(你可以使用它。

但是,如果您的 Stream 包含原始 zip 数据并且您想要做的只是将其保存到磁盘,您应该能够将字节直接写入磁盘。

如果您收到“zip 文件损坏”错误,我会查看用于将数据发送到 Azure 的内容编码以及发送回的内容编码。您应该使用 application/zipapplication/octet-stream 的内容类型将其发送到 Azure,并可能将元数据添加到 Azure blob 条目以以相同的方式发送。


编辑注释: DotNetZip 曾经住在 Codeplex。 Codeplex 已关闭。旧档案仍然是available at Codeplex。看起来代码已经迁移到Github了:


【讨论】:

  • 感谢您的洞察力,明天我会试试 DotNetZip(正在尝试 SharpZipLib,但找不到我要找的东西)。至于内容类型,上传存储来自 RequestMessage 的内容类型,然后从 Blob 中提取,正如您在 sn-p 中看到的那样,所以它应该没问题。
  • 标记为答案,因为我最终需要使用 DotNetZip 便携式才能从我的文件中解压缩。最后,这是我的盲目愚蠢。服务器上的文件流(然后被打包为 StreamContent)将其位置设置为流的末尾。将其设置为 0,我的代码运行良好。我错过了这个,因为在我的客户端消费代码上,没有实现 position 属性,所以我无法评估它!谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-01-17
  • 1970-01-01
  • 2016-02-02
  • 1970-01-01
  • 1970-01-01
  • 2012-07-17
  • 2018-10-21
相关资源
最近更新 更多