2009-08-30 24 views
6

我想使用.NET框架中包含的GZipStream类来解压缩(.gz)文件。我正在使用MSDN文档,并不断收到此异常:“不支持写入压缩流。”不支持写入压缩流。使用System.IO.GZipStream

这里是应用程序源:

try 
      { 

       var infile = new FileStream(@"C:\TarDecomp\TarDecomp\TarDecomp\bin\Debug\nick_blah-2008.tar.gz", FileMode.Open, FileAccess.Read, FileShare.Read); 
       byte[] buffer = new byte[infile.Length]; 
       // Read the file to ensure it is readable. 
       int count = infile.Read(buffer, 0, buffer.Length); 
       if (count != buffer.Length) 
       { 
        infile.Close(); 
        Console.WriteLine("Test Failed: Unable to read data from file"); 
        return; 
       } 
       infile.Close(); 
       MemoryStream ms = new MemoryStream(); 
       // Use the newly created memory stream for the compressed data. 
       GZipStream compressedzipStream = new GZipStream(ms, CompressionMode.Decompress, true); 
       Console.WriteLine("Decompression"); 
       compressedzipStream.Write(buffer, 0, buffer.Length); 
       // Close the stream. 
       compressedzipStream.Close(); 
       Console.WriteLine("Original size: {0}, Compressed size: {1}", buffer.Length, ms.Length); 

例外是在compressedZipStream.write抛出()。

任何想法?这个异常告诉我什么?谢谢!

回答

14

它告诉你,你应该打电话Read而不是Write,因为它是解压缩!此外,内存流应该与数据一起构造,或者您应该将文件流直接传递给GZipStream构造函数。

的应该如何已经完成实例(没试过编译):

Stream inFile = new FileStream(@"C:\TarDecomp\TarDecomp\TarDecomp\bin\Debug\nick_blah-2008.tar.gz", FileMode.Open, FileAccess.Read, FileShare.Read); 
Stream decodedStream = new MemoryStream(); 
byte[] buffer = new byte[4096]; 

using (Stream inGzipStream = new GZipStream(inFile, CompressionMode.Decompress)) 
{ 
    int bytesRead; 
    while ((bytesRead = inGzipStream.Read(buffer, 0, buffer.Length)) > 0) 
     decodedStream.Write(buffer, 0, bytesRead); 
} 

// Now decodedStream contains the decoded data 
+0

我试着这个谢谢你。 – Nick 2009-08-30 19:25:56

+0

你的男人..谢谢! – Nick 2009-08-30 19:27:03

+0

很高兴提供帮助。 :) – 2009-08-30 19:35:04

1

如何压缩流的工作可以先令人费解。

读取需要压缩数据和写入需要未压缩数据。总而言之,数据流确保您始终只能“看到”未压缩的数据。

要实现您正在尝试执行的操作的正确方法是使用GZipStream进行读取,然后再使用GZipStream进行写入。

9

压缩代码不能像加密一样工作 - 通过写入压缩数据,您不能从一个流解压缩到另一个流。您必须提供一个包含压缩数据的流,并让它从中读取。事情是这样的:

using (Stream file = File.OpenRead(filename)) 
using (Stream gzip = new GZipStream(file, CompressionMode.Decompress)) 
using (Stream memoryStream = new MemoryStream()) 
{ 
    CopyStream(gzip, memoryStream); 
    return memoryStream.ToArray(); 
} 

CopyStream是一个简单实用的方法,从一个流中读取所有的数据复制到另一个。这样的事情:

static void CopyStream(Stream input, Stream output) 
{ 
    byte[] buffer = new byte[8192]; 
    int bytesRead; 
    while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0) 
    { 
     output.Write(buffer, 0, bytesRead); 
    } 
}