2015-06-24 29 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,我的代碼完美工作。我錯過了這一點,因爲在我的客戶端消費代碼中,位置屬性沒有實現,所以我無法評估它! 謝謝。 –

相關問題