2013-01-12 53 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