我正在处理文件流阅读:https://msdn.microsoft.com/en-us/library/system.io.filestream.read%28v=vs.110%29.aspx
我尝试做的是一次循环读取一个大文件一定数量的字节;不是一次整个文件。代码示例显示了这一点:
int n = fsSource.Read(bytes, numBytesRead, numBytesToRead);
"字节"的定义是:"当此方法返回时,包含指定的字节数组,其中offset和(offset + count - 1)之间的值被从当前源读取的字节替换。"
我想一次只读1 MB,所以我这样做:
using (FileStream fsInputFile = new FileStream(strInputFileName, FileMode.Open, FileAccess.Read)) {
int intBytesToRead = 1024;
int intTotalBytesRead = 0;
int intInputFileByteLength = 0;
byte[] btInputBlock = new byte[intBytesToRead];
byte[] btOutputBlock = new byte[intBytesToRead];
intInputFileByteLength = (int)fsInputFile.Length;
while (intInputFileByteLength - 1 >= intTotalBytesRead)
{
if (intInputFileByteLength - intTotalBytesRead < intBytesToRead)
{
intBytesToRead = intInputFileByteLength - intTotalBytesRead;
}
// *** Problem is here ***
int n = fsInputFile.Read(btInputBlock, intTotalBytesRead, intBytesToRead);
intTotalBytesRead += n;
fsOutputFile.Write(btInputBlock, intTotalBytesRead - n, n);
}
fsOutputFile.Close(); }
在陈述问题区域的地方,btInputBlock在第一个周期工作,因为它读取1024个字节。但是在第二个循环中,它不会回收这个字节数组。它试图将新的1024字节附加到btInputBlock中。据我所知,您只能指定要读取的文件的偏移量和长度,而不能指定btInputBlock的偏移量和长度。有没有办法重新使用&#34; Filestream.Read正在转储的数组,还是应该找到另一种解决方案?
感谢。
P.S。读取的例外是:&#34;偏移量和长度超出数组的范围,或者计数大于从索引到源集合末尾的元素数量。&#34;
答案 0 :(得分:2)
您的代码可以稍微简化
int num;
byte[] buffer = new byte[1024];
while ((num = fsInputFile.Read(buffer, 0, buffer.Length)) != 0)
{
//Do your work here
fsOutputFile.Write(buffer, 0, num);
}
请注意Read
接受数组填充,偏移(这是应放置字节的数组的偏移量,以及(max)要读取的字节数。
答案 1 :(得分:0)
那是因为您正在递增intTotalBytesRead,这是数组的偏移量,而不是文件流的偏移量。在你的情况下,它应该总是为零,这将覆盖数组中的前一个字节数据,而不是使用intTotalBytesRead将它附加到最后。
int n = fsInputFile.Read(btInputBlock, intTotalBytesRead, intBytesToRead); //currently
int n = fsInputFile.Read(btInputBlock, 0, intBytesToRead); //should be
文件流不需要偏移,每次读取都会从最后一个读取的位置开始。 见https://msdn.microsoft.com/en-us/library/system.io.filestream.read(v=vs.110).aspx 详情
答案 2 :(得分:0)
您的Read
来电应为Read(btInputBlock, 0, intBytesToRead)
。第二个参数是要开始写入字节的数组的偏移量。类似地,对于Write
,您需要Write(btInputBlock, 0, n)
,因为第二个参数是数组中开始写入字节的偏移量。您也不需要致电Close
,因为using
会为您清理FileStream
。
using (FileStream fsInputFile = new FileStream(strInputFileName, FileMode.Open, FileAccess.Read))
{
int intBytesToRead = 1024;
byte[] btInputBlock = new byte[intBytesToRead];
while (fsInputFile.Postion < fsInputFile.Length)
{
int n = fsInputFile.Read(btInputBlock, 0, intBytesToRead);
intTotalBytesRead += n;
fsOutputFile.Write(btInputBlock, 0, n);
}
}