【发布时间】:2012-05-03 00:58:39
【问题描述】:
我有许多从 ftp 下载的大型 gzip 文件(大约 10MB - 200MB)要解压缩。
所以我尝试谷歌并找到一些gzip解压缩的解决方案。
static byte[] Decompress(byte[] gzip)
{
using (GZipStream stream = new GZipStream(new MemoryStream(gzip), CompressionMode.Decompress))
{
const int size = 4096;
byte[] buffer = new byte[size];
using (MemoryStream memory = new MemoryStream())
{
int count = 0;
do
{
count = stream.Read(buffer, 0, size);
if (count > 0)
{
memory.Write(buffer, 0, count);
}
}
while (count > 0);
return memory.ToArray();
}
}
}
它适用于任何低于 50mb 的文件,但是一旦我输入超过 50mb 的文件,就会出现系统内存不足异常。异常前的最后位置和内存长度是 134217728。我认为它与我的物理内存无关,我知道我使用 32 位,所以我不能拥有超过 2GB 的对象。
我还需要在解压文件后处理数据。我不确定内存流是否是这里最好的方法,但我真的不喜欢写入文件然后再次读取文件。
我的问题
- 为什么会出现 System.OutMemoryException?
- 解压 gzip 文件并在之后进行一些文本处理的最佳解决方案是什么?
【问题讨论】:
-
您正在将流的全部内容加载到内存中并将其作为字节数组返回。除了内存不足的异常,您还期望 other 什么?您不应该像这样将它全部加载到内存中——您最终打算对数组做什么?将其写入文件?无论你想要什么,它都应该是基于流的,而不是基于数组的。
-
好吧.. memory.write 发生异常并卡在 134217728 中.. 我不熟悉内存管理,所以请多多包涵。稍后我会将所有处理的文件保存到数据库中,gzipped文件中的文件是csv文件
-
当然,但是如果您在解压缩的同时处理它,您的设计会更好。这样您就不必分配大量内存来处理它。 (例如,通过将 gzip 流直接放入
StreamReader) -
在你的函数原型中最容易发现错误:
static byte[] Decompress(byte[] gzip)。您想将 stream 作为参数,而不是数组。 -
感谢您的建议。我会尝试使用流。
标签: c# gzip out-of-memory compression gzipstream