Search code examples
c#filestream

C# Filestream Read - Recycle array?


I am working with filestream read: https://msdn.microsoft.com/en-us/library/system.io.filestream.read%28v=vs.110%29.aspx

What I'm trying to do is read a large file in a loop a certain number of bytes at a time; not the whole file at once. The code example shows this for reading:

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

The definition of "bytes" is: "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."

I want to only read in 1 mb at a time so I do this:

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(); }

Where the problem area is stated, btInputBlock works on the first cycle because it reads in 1024 bytes. But then on the second loop, it doesn't recycle this byte array. It instead tries to append the new 1024 bytes into btInputBlock. As far as I can tell, you can only specify the offset and length of the file you want to read and not the offset and length of btInputBlock. Is there a way to "re-use" the array that is being dumped into by Filestream.Read or should I find another solution?

Thanks.

P.S. The exception on the read is: "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."


Solution

  • That's because you're incrementing intTotalBytesRead, which is an offset for the array, not for the filestream. In your case it should always be zero, which will overwrite previous byte data in the array, rather than append it at the end, using intTotalBytesRead.

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

    Filestream doesn't need an offset, every Read picks up where the last one left off. See https://msdn.microsoft.com/en-us/library/system.io.filestream.read(v=vs.110).aspx for details