如何将大文件(12gb)拆分为多个1GB压缩(.gz)存档?C#.



我有一个大的.bak文件 - 接近12gb。 我需要在代码中将其拆分为多个 2gb.gz存档。

最大的问题是我需要稍后验证此存档。

你知道就像当你在 3 或 4 个存档上使用 winrar 拆分一个文件时,然后你只需按"解压缩",它就会将它们全部解压缩到一个文件中,或者如果没有足够的档案(你删除一个)就会崩溃。

我需要这样的东西。

public void Compress(DirectoryInfo directorySelected)
{
int writeStat = 0;
foreach (FileInfo fileToCompress in directorySelected.GetFiles())
{
using (FileStream originalFileStream = fileToCompress.OpenRead())
{
if ((File.GetAttributes(fileToCompress.FullName) &
FileAttributes.Hidden) != FileAttributes.Hidden & fileToCompress.Extension != ".gz")
{
bytesToRead = new byte[originalFileStream.Length];
int numBytesRead = bytesToRead.Length;
while (_nowOffset < originalFileStream.Length)
{                                
writeStat = originalFileStream.Read(bytesToRead, 0, homMuchRead);
using (FileStream compressedFileStream = File.Create(fileToCompress.FullName + counter + ".gz"))
{
using (GZipStream compressionStream = new GZipStream(compressedFileStream,
CompressionMode.Compress))
{
compressionStream.Write(bytesToRead, 0, writeStat);
}
}
_nowOffset = _nowOffset + writeStat;                        
counter++;
}
FileInfo info = new FileInfo(directoryPath + Path.DirectorySeparatorChar + fileToCompress.Name + ".gz");
//Console.WriteLine($"Compressed {fileToCompress.Name} from {fileToCompress.Length.ToString()} to {info.Length.ToString()} bytes.");
}
}
}
}

它运行良好,但我不知道如何验证他们的计数。

我在测试对象上有 7 个存档。但是如何在一个文件中读取它们,并验证此文件是否已满。

GZip 格式本身不支持您想要的内容。

Zip可以,该功能称为"跨区存档",但.NET的ZipArchive类则不然。您需要一个第三方库,例如DotNetZip。

但是有解决方法。

创建一个从抽象类继承Stream类,外部假装它是一个可以写入但不能读取或查找的单个流,在实现中写入多个部分,每个 2GB。在实现中使用 .NET 提供的 FileStream。跟踪班级long字段中写入的总长度。一旦下一个 Write() 调用超过 2GB,只需写入足够的字节以达到 2GB,关闭并释放底层 FileStream,使用下一个文件名打开另一个文件,将文件长度计数器重置为 0,然后将剩余字节从缓冲区写入 Write() 调用。重复直到关闭。

创建自定义流的实例,传递给 GZipStream 的构造函数,并将完整的 12GB 源数据复制到 GZipStream 中。

如果你做对了,在输出时,你将拥有大小正好为 2GB 的文件(最后一个除外)。

要读取和解压缩它们,您需要使用自定义流实现类似的技巧。编写一个动态连接多个文件的流类,假装它是单个流,但这次你只需要实现Read()方法。将该串联流从框架提供给GZipStream。如果您要重新订购或销毁某些部件,则GZipStream无法解压缩的可能性非常高(但不是 100%),抱怨 CRC 校验和。

附言为了实现和调试上述 2 个流,我建议使用更小的数据集,例如 12 MB 的数据,拆分为 1MB 压缩部分。一旦你让它工作,增加常量并使用完整的 12GB 数据进行测试。

最新更新