2013-01-12 66 views
7

我想了解爲什麼我的代碼不能按需要執行。它創建一個GZipStream,然後將對象保存爲壓縮文件到我的硬盤上,但保存的文件總是0字節。用GZipStream壓縮

現在我知道如何save a file using GZipStream,但是,我的問題不是如何去做。我的問題純粹是爲什麼此代碼保存0字節(或爲什麼FileStream工作和內存不)。

private void BegingCompression() 
{ 
    var bytes = File.ReadAllBytes(this.fileName); 
    using (MemoryStream ms = new MemoryStream(bytes)) 
    { 
     ms.ReadByte(); 
     using (FileStream fs =new FileStream(this.newFileName, FileMode.CreateNew)) 
     using (GZipStream zipStream = new GZipStream(ms, CompressionMode.Compress, false)) 
     { 
      zipStream.Write(bytes, 0, bytes.Length); 
     } 
    } 
} 

在問候的源代碼,this.fileName = c:\Audio.wavnewFileNamec:\Audio.wav.gz(但也嘗試c:\audio.gz

回答

9
  • 您不需要MemoryStream,因爲bytes已經有要壓縮的數據。
  • ms.ReadByte()不應使用。
  • 創建zipStream時,應使用輸出文件流。

試試這個:

var bytes = File.ReadAllBytes(this.fileName); 
using (FileStream fs =new FileStream(this.newFileName, FileMode.CreateNew)) 
using (GZipStream zipStream = new GZipStream(fs, CompressionMode.Compress, false)) 
{ 
    zipStream.Write(bytes, 0, bytes.Length); 
} 

編輯

原來的代碼創建了一個長度爲零的文件,因爲你不寫文件流。

+0

您是否看過他的問題? – SergeyS

+0

謝謝@SergeyS。我會編輯它。 –

+0

您可能還想考慮轉換爲MP3;請參閱http://www.codeproject.com/Articles/5901/C-MP3-Compressor –

2
why FileStream works and memory doesn't 

由於的MemoryStream的後備存儲是你的RAM內存,沒有硬盤驅動器。所以當你將MemoryStream對象傳遞給GZipStream的構造函數時,你的gzip只會在RAM中。

有了這個代碼:

using (FileStream fs =new FileStream(this.newFileName, FileMode.CreateNew)) 

要創建新的FileStream,但您沒有使用它。要使用此FIleStream存儲gzip,您需要將其傳遞給GZipStream構造函數,以使其支持存儲爲硬盤驅動器。

7

當您使用GzipStreamDeflateStreamSystem.IO.Compression命名空間,你在構造供應Stream寫入壓縮減壓讀取。

既然你想壓縮這裏的數據,使用MemoryStream是不正確的,你是不是想壓縮到它,而是把它作爲數據源。所以你的MemoryStream應該是輸入StreamFileStream是你的輸出。

我強烈建議你使用MemoryStream作爲遍生byte[]因爲Stream有很多更多的功能和應用(FileStreamNetworkStreamCryptoStream等數據源)

下面是使用async/await模式的一些例子:

public static async Task CompressToFileAsync(byte[] buffer, 
              string outputFile) 
{ 
    using (var inputStream = new MemoryStream(buffer)) 
    await CompressToFileAsync(inputStream, outputFile); 
} 

public static async Task CompressToFileAsync(Stream inputStream, 
              string outputFile) 
{ 
    using (var outputStream = File.Create(outputFile)) 
    using (var gzip = new GZipStream(outputStream, CompressionMode.Compress)) 
    { 
    await inputStream.CopyToAsync(gzip); 
    gzip.Close(); 
    } 
} 

public static async Task<MemoryStream> DecompressFromFileAsync(string inputFile) 
{ 
    var outputStream = new MemoryStream(); 

    using (var inputStream = File.Open(inputFile, FileMode.Open, FileAccess.Read, FileShare.Read)) 
    using (var gzip = new GZipStream(inputStream, CompressionMode.Decompress)) 
    { 
    await gzip.CopyToAsync(outputStream); 

    gzip.Close(); 
    inputStream.Close(); 

    // After writing to the MemoryStream, the position will be the size 
    // of the decompressed file, we should reset it back to zero before returning. 
    outputStream.Position = 0; 
    return outputStream; 
    } 
} 

注:總是調用GzipStream.Close()您關閉輸入輸出Stream之前。當關閉/處置時,它會執行一些最終的緩衝區刷新,並且如果輸入輸出先關閉,它會在嘗試這樣做時拋出異常。 (這也適用於DeflateStream