FileStream在128字节后从A读取并写入B C#
本文关键字:读取 字节 FileStream | 更新日期: 2023-09-27 17:49:32
我有一个大文件(大约400GB(,我需要对其进行FileStream并将前128个字节跳过到另一个文件中。我有下面的代码,但它不能正常工作,因为当我在流完成后检查文件大小时,文件B丢失了超过128个字节。我做错了什么?
private void SplitUnwantedHeader(string file1, string file2)
{
FileStream fr = new FileStream(file1, FileMode.Open, FileAccess.Read);
FileStream fw = new FileStream(file2, FileMode.Create, FileAccess.Write);
byte[] fByte = new byte[65534];
long headerToSplit = 128;
int bytesRead = 0;
try
{
fr.Position = headerToSplit;
do
{
bytesRead = fr.Read(fByte, 0, fByte.Length);
fw.Write(fByte, 0, fByte.Length - (int)headerToSplit);
} while (bytesRead != 0);
}
catch (Exception ex)
{
UpdateStatusBarMessage.ShowStatusMessage(ex.Message);
}
finally
{
fw.Close();
fr.Close();
}
}
谢谢。
行
fw.Write(fByte, 0, fByte.Length - (int)headerToSplit);
在这样的循环中使用时,是错误的。它将在每个循环周期写入"缓冲区大小">减去128个字节。相反,代码应该在复制期间写入bytesRead
计数。
fw.Write(fByte, 0, bytesRead);
仅在进入复制所有其他循环之前执行偏移量。此外,循环可以替换为FileStream.CopyTo
(由于.NET4(,并且使用可以整理资源管理。
也就是说,考虑一下:
using (var fr = new FileStream(file1, FileMode.Open, FileAccess.Read))
using (var fw = new FileStream(file2, FileMode.Create, FileAccess.Write)) {
fr.Position = 128; // or fr.Seek(128, SeekOrigin.Begin);
fr.CopyTo(fw, 65534);
}
代码有两个错误:
- 它不是跳过第一个块的前128个字节,而是跳过每个块的最后128个字节
- 它在写入时忽略
bytesRead
值,因此它可能正在将从未读取过的缓冲区中的数据写入缓冲区。读取的字节数可以小于请求的字节数,即使您不在文件末尾
代码是跳过循环前的标头和跳过循环内的标头的混合。你应该做一个,而不是两个都做。
您可以检查缓冲区中的数据量与应该跳过的数据量,并更新要跳过的字节数,使其在超出标头后为零:
do {
bytesRead = fr.Read(fByte, 0, fByte.Length);
if (bytesRead > headerToSplit) {
fw.Write(fByte, (int)headerToSplit, bytesRead - (int)headerToSplit);
headerToSplit = 0;
} else {
headerToSplit -= bytesRead;
}
} while (bytesRead != 0);
或者,如果您在循环之前跳过标题,只需写入缓冲区中的所有数据:
fr.Position = headerToSplit;
do {
bytesRead = fr.Read(fByte, 0, fByte.Length);
fw.Write(fByte, 0, bytesRead);
} while (bytesRead != 0);