大数据上的 GZipStream
Posted
技术标签:
【中文标题】大数据上的 GZipStream【英文标题】:GZipStream on large data 【发布时间】:2012-05-16 15:29:53 【问题描述】:我正在尝试压缩大量数据,有时在 100GB 的区域内,当我运行我编写的例程时,它看起来文件的大小与之前的大小完全相同。 GZipStream 有其他人遇到过这个问题吗?
我的代码如下:
byte[] buffer = BitConverter.GetBytes(StreamSize);
FileStream LocalUnCompressedFS = File.OpenWrite(ldiFileName);
LocalUnCompressedFS.Write(buffer, 0, buffer.Length);
GZipStream LocalFS = new GZipStream(LocalUnCompressedFS, CompressionMode.Compress);
buffer = new byte[WriteBlock];
UInt64 WrittenBytes = 0;
while (WrittenBytes + WriteBlock < StreamSize)
fromStream.Read(buffer, 0, (int)WriteBlock);
LocalFS.Write(buffer, 0, (int)WriteBlock);
WrittenBytes += WriteBlock;
OnLDIFileProgress(WrittenBytes, StreamSize);
if (Cancel)
break;
if (!Cancel)
double bytesleft = StreamSize - WrittenBytes;
fromStream.Read(buffer, 0, (int)bytesleft);
LocalFS.Write(buffer, 0, (int)bytesleft);
WrittenBytes += (uint)bytesleft;
OnLDIFileProgress(WrittenBytes, StreamSize);
LocalFS.Close();
fromStream.Close();
StreamSize 是一个 8 字节的 UInt64 值,用于保存文件的大小。我将这 8 个字节原始写入文件的开头,所以我知道原始文件的大小。 Writeblock 的值为 32kb(32768 字节)。 fromStream 是从 FileStream 获取数据的流。压缩数据前面的 8 个字节是否会导致问题?
【问题讨论】:
您的代码是否适用于较小的文件? 您能否确认您的代码正确压缩了较小的数据集 - 例如,您知道通常可以很好地压缩的文本文件... 【参考方案1】:我使用以下代码进行了压缩测试,它在 7GB 和 12GB 文件上运行没有问题(两者都事先知道压缩“好”)。这个版本适合你吗?
const string toCompress = @"input.file";
var buffer = new byte[1024*1024*64];
using(var compressing = new GZipStream(File.OpenWrite(@"output.gz"), CompressionMode.Compress))
using(var file = File.OpenRead(toCompress))
var bytesRead = 0;
while(bytesRead < buffer.Length)
bytesRead = file.Read(buffer, 0, buffer.Length);
compressing.Write(buffer, 0, buffer.Length);
你检查过documentation吗?
GZipStream 类无法解压缩导致超过 8 GB 未压缩数据的数据。
您可能需要找到一个不同的库来支持您的需求,或者尝试将您的数据分解为可以安全地“缝合”在一起的 <=8GB
块。
【讨论】:
嗨,奥斯汀,感谢您的回答。我的程序不会解压缩,所以我认为这不重要吗?除非压缩也有 8gb 的限制。 嗯...如果您需要更多呢?还有其他选择吗?流会有这种限制似乎很奇怪。 说解压,OP说压缩。 @Skintkingle:您现在如何测试代码的有效性? 嗨,Austin,我还没有确认代码压缩适用于较小的数据集,尽管我看不到代码 sn-p 'not' 工作。一秒钟让我将 StreamSize 设置为小一点,这样它只需要一部分数据,看看压缩后的大小是否更小。【参考方案2】:Austin Salonen 的代码对我不起作用(错误,4GB 错误)。
这是正确的方法:
using System;
using System.Collections.Generic;
using System.Text;
namespace CompressFile
class Program
static void Main(string[] args)
string FileToCompress = @"D:\Program Files (x86)\msvc\wkhtmltopdf64\bin\wkhtmltox64.dll";
FileToCompress = @"D:\Program Files (x86)\msvc\wkhtmltopdf32\bin\wkhtmltox32.dll";
string CompressedFile = System.IO.Path.Combine(
System.IO.Path.GetDirectoryName(FileToCompress)
,System.IO.Path.GetFileName(FileToCompress) + ".gz"
);
CompressFile(FileToCompress, CompressedFile);
// CompressFile_AllInOne(FileToCompress, CompressedFile);
Console.WriteLine(Environment.NewLine);
Console.WriteLine(" --- Press any key to continue --- ");
Console.ReadKey();
// End Sub Main
public static void CompressFile(string FileToCompress, string CompressedFile)
//byte[] buffer = new byte[1024 * 1024 * 64];
byte[] buffer = new byte[1024 * 1024]; // 1MB
using (System.IO.FileStream sourceFile = System.IO.File.OpenRead(FileToCompress))
using (System.IO.FileStream destinationFile = System.IO.File.Create(CompressedFile))
using (System.IO.Compression.GZipStream output = new System.IO.Compression.GZipStream(destinationFile,
System.IO.Compression.CompressionMode.Compress))
int bytesRead = 0;
while (bytesRead < sourceFile.Length)
int ReadLength = sourceFile.Read(buffer, 0, buffer.Length);
output.Write(buffer, 0, ReadLength);
output.Flush();
bytesRead += ReadLength;
// Whend
destinationFile.Flush();
// End Using System.IO.Compression.GZipStream output
destinationFile.Close();
// End Using System.IO.FileStream destinationFile
// Close the files.
sourceFile.Close();
// End Using System.IO.FileStream sourceFile
// End Sub CompressFile
public static void CompressFile_AllInOne(string FileToCompress, string CompressedFile)
using (System.IO.FileStream sourceFile = System.IO.File.OpenRead(FileToCompress))
using (System.IO.FileStream destinationFile = System.IO.File.Create(CompressedFile))
byte[] buffer = new byte[sourceFile.Length];
sourceFile.Read(buffer, 0, buffer.Length);
using (System.IO.Compression.GZipStream output = new System.IO.Compression.GZipStream(destinationFile,
System.IO.Compression.CompressionMode.Compress))
output.Write(buffer, 0, buffer.Length);
output.Flush();
destinationFile.Flush();
// End Using System.IO.Compression.GZipStream output
// Close the files.
destinationFile.Close();
// End Using System.IO.FileStream destinationFile
sourceFile.Close();
// End Using System.IO.FileStream sourceFile
// End Sub CompressFile
// End Class Program
// End Namespace CompressFile
【讨论】:
以上是关于大数据上的 GZipStream的主要内容,如果未能解决你的问题,请参考以下文章