Dic*_*ick 1 c# out-of-memory binarywriter
我试图将文件添加到Zip文件,保留目录.下面的代码基本上是工作的,只要我没有几个100 Mb的文件压缩.如果我只用一个大约250 Mb的文件压缩一个目录(在一个有足够内存BTW的系统上),我就会得到一个OutOfMemory异常write.Write().
我已经修改了代码以读取块,因为它在读取/写入整个文件时首次失败.我不知道为什么它仍然失败?
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();
}
Run Code Online (Sandbox Code Playgroud)
编辑:Arkadiusz K是对的,我在阅读器上使用了同花顺,而不是作家.更改之后,程序将首先停止在100 Mb的1 Gb或更多文件.但是,当我尝试压缩例如6 Gb文件时,我得到另一个例外 - 它停止:System.IO.IOException未处理Stream太长 Source = mscorlib StackTrace:at System.IO.MemoryStream.Write(Byte [] buffer ,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();
}
}
Run Code Online (Sandbox Code Playgroud)
现在,解释它失败的原因:
BinaryWriter是一个流编写器.当它必须将数据写入流时,它通常将其写为长度前缀并且:
Length-prefixed表示当使用BinaryWriter实例的当前编码对流进行编码时,此方法首先写入字符串的长度(以字节为单位).该值写为无符号整数.然后,此方法将许多字节写入流.
为了写入文件,在您的情况下,数据首先写入MemoryStream.这里,MemoryStream是后备存储流.请参考下图:
(图片来自:http://kcshadow.net/wpdeveloper/sites/default/files/streamd3.png)
因为您的系统内存大约为6-8GB,或者因为您的应用程序仅分配了大量内存,所以当您尝试压缩6GB文件时,后备存储流会扩展到最大值,然后抛出异常.
| 归档时间: |
|
| 查看次数: |
2271 次 |
| 最近记录: |