如何从 MemoryStream 重新创建 Zip 文件
How to recreate a Zip File from a MemoryStream
我四处寻找问题的解决方案,但似乎没有人以我想要实现的目标为目标。
我的问题是这样的,我在 Azure Blob 存储中存储了 Zip 文件,现在为了安全起见,我们有一个 API2 控制器操作来提供这些 zip 文件,而不是允许直接下载。此操作将检索 blob,并将其下载到流中,以便将其打包在 HTTPResponseMessage
中。
以上所有方法都有效,但是,当我尝试重新创建 zip 文件时,我被告知它已损坏。现在我只是试图让服务器(本地主机上的 运行)创建 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 文件读入流,或者创建以便提供文件下载而不是文件创建。
非常感谢任何帮助,谢谢。
您使用 DotNetZip
. Its ZipFile
class has a static factory method that should do what you want: ZipFile.Read( Stream zipStream )
将给定的流读取为 zip 文件并返回一个 ZipFile
实例(您可以将其用于任何用途。
但是,如果您的 Stream
包含原始 zip 数据,而您只想将其保存到磁盘,那么您应该能够直接将字节写入磁盘。
如果您收到 'zip file corrupted' 错误,我会查看用于将数据发送到 Azure 的内容编码以及它发回时使用的内容编码。您应该使用 application/zip
或 application/octet-stream
的内容类型将其发送到 Azure,并可能将元数据添加到 Azure blob 条目以将其以相同的方式发送。
编辑注意: DotNetZip 曾经住在 Codeplex。 Codeplex 已关闭。旧存档仍然是available at Codeplex。看起来代码已经迁移到 Github:
- https://github.com/DinoChiesa/DotNetZip。看起来是原作者的回购。
- https://github.com/haf/DotNetZip.Semverd. This looks to be the currently maintained version. It's also packaged up an available via Nuget at https://www.nuget.org/packages/DotNetZip/
我四处寻找问题的解决方案,但似乎没有人以我想要实现的目标为目标。
我的问题是这样的,我在 Azure Blob 存储中存储了 Zip 文件,现在为了安全起见,我们有一个 API2 控制器操作来提供这些 zip 文件,而不是允许直接下载。此操作将检索 blob,并将其下载到流中,以便将其打包在 HTTPResponseMessage
中。
以上所有方法都有效,但是,当我尝试重新创建 zip 文件时,我被告知它已损坏。现在我只是试图让服务器(本地主机上的 运行)创建 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 文件读入流,或者创建以便提供文件下载而不是文件创建。
非常感谢任何帮助,谢谢。
您使用 DotNetZip
. Its ZipFile
class has a static factory method that should do what you want: ZipFile.Read( Stream zipStream )
将给定的流读取为 zip 文件并返回一个 ZipFile
实例(您可以将其用于任何用途。
但是,如果您的 Stream
包含原始 zip 数据,而您只想将其保存到磁盘,那么您应该能够直接将字节写入磁盘。
如果您收到 'zip file corrupted' 错误,我会查看用于将数据发送到 Azure 的内容编码以及它发回时使用的内容编码。您应该使用 application/zip
或 application/octet-stream
的内容类型将其发送到 Azure,并可能将元数据添加到 Azure blob 条目以将其以相同的方式发送。
编辑注意: DotNetZip 曾经住在 Codeplex。 Codeplex 已关闭。旧存档仍然是available at Codeplex。看起来代码已经迁移到 Github:
- https://github.com/DinoChiesa/DotNetZip。看起来是原作者的回购。
- https://github.com/haf/DotNetZip.Semverd. This looks to be the currently maintained version. It's also packaged up an available via Nuget at https://www.nuget.org/packages/DotNetZip/