C#Filestream Read - 回收数组?

时间:2015-03-17 18:05:54

标签: c# filestream

我正在处理文件流阅读: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;

3 个答案:

答案 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);
    }
}