C# 文件流读取 - 回收数组?

C# Filestream Read - Recycle array?

我正在使用文件流读取:https://msdn.microsoft.com/en-us/library/system.io.filestream.read%28v=vs.110%29.aspx

我想做的是在循环中一次读取一个大文件一定数量的字节;不是一次整个文件。代码示例显示了这一点以供阅读:

int n = fsSource.Read(bytes, numBytesRead, numBytesToRead);

"bytes"的定义是:"When this method returns, contains the specified byte array with the values between offset and (offset + count - 1) replaced by the bytes read from the current source."

我想一次只读取 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 的偏移量和长度。有没有办法 "re-use" 被 Filestream.Read 转储到的数组,或者我应该找到另一个解决方案?

谢谢。

P.S。读取的异常是:"Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection."

您的代码可以稍微简化

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接受数组来填充offset(这是数组的偏移量,其中应放置字节,以及要读取的(最大)字节数

那是因为您正在递增 intTotalBytesRead,它是数组的偏移量,而不是文件流的偏移量。在您的情况下,它应该始终为零,这将覆盖数组中的先前字节数据,而不是使用 intTotalBytesRead 将其附加在末尾。

int n = fsInputFile.Read(btInputBlock, intTotalBytesRead, intBytesToRead); //currently
int n = fsInputFile.Read(btInputBlock, 0, intBytesToRead); //should be

Filestream 不需要偏移量,每次读取都从上一次停止的地方开始。 参见 https://msdn.microsoft.com/en-us/library/system.io.filestream.read(v=vs.110).aspx 详情

您的 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);
    }
}