2015-06-24 32 views
1

重新创建一个ZIP文件,我环顾四周,为解决我的问题,但没有人似乎是瞄准了相当我想达到的目标。如何从一个MemoryStream

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

以上所有作品,但是,当我试图重新压缩文件,我告诉它的损坏。现在我只是试图让服务器(在本地主机上运行)创建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文件到流,或创建为了提供文件下载,而不是filecreate。

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

+1

它取决于zip文件大小吗?如果你尝试使用小于1 Mb的小zip文件,你还有问题吗?您也可以尝试执行fileStream.ToArray(),它会为您提供一个byte [] arryay与您的流的内容。 –

+0

@AlexShapovalov好了,.ToArray()工作对我来说,基本上我的问题是,filestream.Read不能正常工作,它写入正确的字节数量,但他们都有0的ToArray(值)创建相同大小的字节数组,但字节实际上有值。 我的下一个问题是,我的客户端上,流这么把它变成一个MemoryStream可能是比较麻烦的一个WebConnectionStream,但我会在现在! :) –

回答

2

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

但是,如果你的Stream包含原始的zip数据和所有你想要做的就是坚持到磁盘,你应该能够直接写入磁盘的字节。

如果你得到'zip文件损坏'的错误,我会看看用于将数据发送到Azure和内容内容编码方式进行编码它送回来了。你应该在发送了内容类型的application/zipapplication/octet-stream到Azure和可能添加元数据到Azure的BLOB条目以相同的方式发送。

+0

感谢您的洞察力,我明天会给DotNetZip一个去(正在尝试SharpZipLib,并找不到我在找什么)。至于内容类型,上传将RequestMessage中的内容类型存储起来,然后将它从Blob中提取出来,就像你在代码片段中看到的一样,所以它应该是可以的。 –

+0

标记为答案,因为我最终需要使用DotNetZip portable来从我的文件中解压缩。 最后,我是盲目的愚蠢。服务器上的文件流(然后打包为StreamContent)将其位置设置为流的末尾。将其设置为0,我的代码完美工作。我错过了这一点,因为在我的客户端消费代码中,位置属性没有实现,所以我无法评估它! 谢谢。 –

相关问题