2014-02-28 68 views
0

我一直在尝试在我的一个程序中实现压缩方法。我希望它接受一个流,压缩它并返回压缩流(它返回一个流,因为我希望能够将该流传递给另一个函数,而不必将其保存到文件并在稍后重新读取) 。我有基于MSDN的例子为GZipStream工作测试版本,这就是我来到了,当我试图将其转换为以中和返回流:压缩流

public static Stream compress(Stream fileToCompress) 
{ 
    using (MemoryStream compressedFileStream = new MemoryStream()) 
    { 
     using (GZipStream compressionStream = new GZipStream(compressedFileStream, CompressionMode.Compress)) 
     { 
      fileToCompress.CopyTo(compressionStream); 
      return compressionStream; 
     } 
    } 
} 

返回的流保存到一个文件中(在另一种方法中)导致创建一个0字节的文件(相当有效的压缩,呵呵?)。

我试过寻找othersolutions,但是我一直没有找到任何使用流的东西,而且我试图将运行转换成相同的问题。

编辑:只是为了记录,我已经尝试使用DeflateStream来获得相同的结果。

EDIT2:原来是测试程序没有正确保存。谢谢您的帮助。

回答

2

如果你的目标是要返回流,你需要而不是把它放在using块。

事情是这样的:

public static Stream compress(Stream fileToCompress) { 
    MemoryStream compressedFileStream = new MemoryStream(); 
    GZipStream compressionStream = new GZipStream(compressedFileStream, CompressionMode.Compress); 
    fileToCompress.CopyTo(compressionStream); 
    compressionStream.Seek(0, SeekOrigin.Begin); // Reset to stream start. 
    return compressionStream; 
} 

否则,当流离开using块,它呼吁流Dispose()

编辑:另外,复制后,流“指针”是在结束。您需要将指针重新设置为开始。在保存之前 - 显示在这里。

编辑:删除所有使用块。如果您需要发布流,可以手动完成。

+0

请注意,您的示例实际上关闭了会导致相同的“读取/写入处置流”异常的基础流。 –

+0

我对'MemoryStream'和'GZipStream'的交互作用并不是100%确定的,所以我愿意接受。我的编辑删除使用。 –

+0

感谢您的快速响应。我想我以前曾尝试过,但没有奏效。我再次尝试,只是为了确保,而且我仍然遇到问题。也@AlexeiLevenkov,它没有抛出任何异常,它只是返回一个空的流。 – user3299958

0

您可以按照Steven Hansen的建议跳过using/Dispose调用,但使用压缩数据返回MemoryStream的新副本可能会更干净。

public static Stream compress(Stream fileToCompress) 
{ 
    using (MemoryStream compressedFileStream = new MemoryStream()) 
    { 
     using (var compressionStream = new GZipStream(
      compressedFileStream, CompressionMode.Compress)) 
     { 
      fileToCompress.CopyTo(compressionStream); 
     } 
     return new MemoryStream(compressionStream.ToArray()); 
    } 
} 

如果你想保持单一内存流 - 使用调用删除,不要忘记重新定位流。

var compressedFileStream = new MemoryStream(); 
var compressionStream = new GZipStream(
      compressedFileStream, CompressionMode.Compress); 
fileToCompress.CopyTo(compressionStream); 
// Flush to make sure all data written by compression stream. 
compressionStream.Flush(); 
compressedFileStream.Position = 0; 
return compressedFileStream; 

注意,如果你的文件是非常大的使用临时文件来存储压缩/非压缩流可能会更快由于MemoryStream使用的内存分配策略 - 尝试都和措施。