C# 压缩流
我一直在尝试在我的一个程序中实现一种压缩方法。我希望它接收一个流,对其进行压缩,然后返回压缩后的流(它返回一个流,因为我希望能够将流传递给另一个函数,而不必将其保存到文件中并在以后重新读取)。我有一个基于msdn示例的工作测试版本,这是我在尝试将其转换为接收和返回流时想到的:C# 压缩流,c#,stream,compression,C#,Stream,Compression,我一直在尝试在我的一个程序中实现一种压缩方法。我希望它接收一个流,对其进行压缩,然后返回压缩后的流(它返回一个流,因为我希望能够将流传递给另一个函数,而不必将其保存到文件中并在以后重新读取)。我有一个基于msdn示例的工作测试版本,这是我在尝试将其转换为接收和返回流时想到的: public static Stream compress(Stream fileToCompress) { using (MemoryStream compressedFileStream = new Memor
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字节的文件(相当高效的压缩,嗯?)
我已经试着寻找,但我没有找到任何使用流的,我尝试转换运行到相同的问题
编辑:为了记录在案,我尝试使用DeflateStream获得相同的结果
EDIT2:原来是测试程序没有正确保存。感谢您的帮助。如果您的目标是返回流,则不需要使用将其放入
块
大概是这样的:
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;
}
否则,当流使用
块离开时,它将调用流上的Dispose()
编辑:同样,在复制之后,流“指针”位于末尾。您需要将指针设置回起始位置。保存前-如图所示
编辑:删除所有使用块。如果您需要释放流,可以手动执行。您可以按照Steven Hansen的建议,使用
/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
中使用了内存分配策略-请尝试这两种方法并进行测量。请注意,您的示例实际上关闭了底层流,这将导致相同的“读取/写入已处理流”例外。我不能100%确定MemoryStream
和GZipStream
的交互作用,所以我相信你的话。我的编辑删除了使用。感谢您的快速响应。我想我以前试过,但没用。我又试了一次,只是想确定一下,但我还是遇到了这个问题。另外@AlexeiLevenkov,它没有抛出任何异常,它只是返回一个空流。@user3299958-我在我的帖子中放了一个应该有用的示例。请确保阅读此搜索中涉及0字节文件问题的答案。我已编辑以显示查找流的代码。在您保存之前,需要这样做。