[英]Out of memory using BinaryWriter in C# on adding files to a zip file
我试图将文件添加到Zip文件中,保留目录。 只要我没有几个要压缩的100 Mb文件,下面的代码就可以正常工作。 如果我仅压缩一个包含约250 Mb的文件的目录(在具有大量内存的BTW系统上),则在write.Write()
行上会收到OutOfMemory异常。
我已经修改了代码以读取块,因为当我读取/写入整个文件时它第一次失败。 我不知道为什么它仍然会失败?
using (FileStream zipToOpen = new FileStream(cZipName, eFileMode))
ZipArchiveEntry readmeEntry = archive.CreateEntry(cFileToBackup
);
using (BinaryWriter writer = new BinaryWriter(readmeEntry.Open()))
{
FileStream fsData = null; // Load file into FileStream
fsData = new FileStream(cFileFull, FileMode.Open, FileAccess.Read);
{
byte[] buffer = new byte[1024];
int bytesRead = 0;
while ((bytesRead = fsData.Read(buffer, 0, buffer.Length)) > 0)
{
writer.Write(buffer,0,bytesRead); // here it fails
fsData.Flush(); // ->CHANGED THIS TO writer.Flush() SOLVED IT - nearly..
}
}
fsData.Close();
}
编辑 :Arkadiusz K是对的,我在读者而非作家上使用了同花顺。 更改后,该程序将1 Gb或更大容量的文件压缩到最初以100 Mb停止的位置。 但是,当我尝试压缩6 Gb文件时,我遇到另一个异常-它以以下方式停止:System.IO.IOException未处理流太长 Source = mscorlib StackTrace:位于System.IO.MemoryStream.Write(Byte []缓冲区) ,Int32偏移量,Int32计数)(等)
有人知道为什么它仍然会失败吗? 我想说代码现在应该一次正确读写1 Kb?
首先,我真的很想格式化您的代码,并使其尽可能简洁:
var readmeEntry = archive.CreateEntry(cFileToBackup);
using (var fsData = new FileStream(cFileFull, FileMode.Open, FileAccess.Read))
using (var writer = new BinaryWriter(readmeEntry.Open()))
{
var buffer = new byte[1024];
int bytesRead;
while ((bytesRead = fsData.Read(buffer, 0, buffer.Length)) > 0)
{
writer.Write(buffer, 0, bytesRead); // here it fails
writer.Flush();
}
}
现在,解释为什么失败:
BinaryWriter是流作家。 当必须将数据写入流时,通常将其写入长度前缀并:
长度前缀表示在使用BinaryWriter实例的当前编码对流进行编码时,此方法首先将字符串的长度(以字节为单位)写入。 此值写为无符号整数。 然后,此方法将那么多字节写入流中。
为了写入文件,在您的情况下,首先将数据写入MemoryStream。 在这里,MemoryStream是后备存储流。 请参考下图:
(图片来自: http : //kcshadow.net/wpdeveloper/sites/default/files/streamd3.png )
因为您的系统内存约为6-8GB,或者仅为应用程序分配了那么多的内存,所以当您尝试压缩6GB的文件时,后备存储流将扩展到最大可能的大小,然后引发异常。
关于您的编辑:遇到了同样的问题。 经过一番挖掘后,我发现zipFileEntry.Open()
返回了WrappedStream
,它是基础流(在完成写入之前无法刷新的流)。
这是WrappedStream
的问题:最大长度为WrappedStream
。 我找不到解决该问题的方法,因此最终完全使用了另一个压缩库。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.