简体   繁体   中英

Can't read FileStream into byte[] correctly

I have some C# code to call as TF(true,"C:\\input.txt","C:\\noexistsyet.file") , but when I run it, it breaks on FileStream.Read() for reading the last chunk of the file into the buffer, getting an index-out-of-bounds ArgumentException .

To me, the code seems logical with no overflow for trying to write to the buffer. I thought I had all that set up with rdlen and _chunk , but maybe I'm looking at it wrong. Any help?

My error: ArgumentException was unhandled: 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.

public static bool TF(bool tf, string filepath, string output)
    {
        long _chunk = 16 * 1024; //buffer count
        long total_size = 0
        long rdlen = 0;
        long wrlen = 0;
        long full_chunks = 0;
        long end_remain_buf_len = 0;
        FileInfo fi = new FileInfo(filepath);
        total_size = fi.Length;
        full_chunks = total_size / _chunk;
        end_remain_buf_len = total_size % _chunk;
        fi = null;
        FileStream fs = new FileStream(filepath, FileMode.Open);
        FileStream fw = new FileStream(output, FileMode.Create);
        for (long chunk_pass = 0; chunk_pass < full_chunks; chunk_pass++)
        {
            int chunk = (int)_chunk * ((tf) ? (1 / 3) : 3); //buffer count for xbuffer
            byte[] buffer = new byte[_chunk];
            byte[] xbuffer = new byte[(buffer.Length * ((tf) ? (1 / 3) : 3))];
            //Read chunk of file into buffer
            fs.Read(buffer, (int)rdlen, (int)_chunk); //ERROR occurs here
            //xbuffer = do stuff to make it *3 longer or *(1/3) shorter;
            //Write xbuffer into chunk of completed file
            fw.Write(xbuffer, (int)wrlen, chunk);
            //Keep track of location in file, for index/offset
            rdlen += _chunk;
            wrlen += chunk;
        }
        if (end_remain_buf_len > 0)
        {
                byte[] buffer = new byte[end_remain_buf_len];
                byte[] xbuffer = new byte[(buffer.Length * ((tf) ? (1 / 3) : 3))];
                fs.Read(buffer, (int)rdlen, (int)end_remain_buf_len); //error here too
                //xbuffer = do stuff to make it *3 longer or *(1/3) shorter;
                fw.Write(xbuffer, (int)wrlen, (int)end_remain_buf_len * ((tf) ? (1 / 3) : 3));
                rdlen += end_remain_buf_len;
                wrlen += chunk;
        }
        //Close opened files
        fs.Close();
        fw.Close();
        return false; //no functionality yet lol
    }

The Read() method of Stream (the base class of FileStream ) returns an int indicating the number of bytes read, and 0 when it has no more bytes to read, so you don't even need to know the file size beforehand:

public static void CopyFileChunked(int chunkSize, string filepath, string output)
{
    byte[] chunk = new byte[chunkSize];

    using (FileStream reader = new FileStream(filepath, FileMode.Open))
    using (FileStream writer = new FileStream(output, FileMode.Create))
    {
        int bytes;
        while ((bytes = reader.Read(chunk , 0, chunkSize)) > 0)
        {
            writer.Write(chunk, 0, bytes);
        }
    }
}

Or even File.Copy() may do the trick, if you can live with letting the framework decide about the chunk size.

I think it's failing on this line:

  fw.Write(xbuffer, (int)wrlen, chunk);

You are declaring xbuffer as

 byte[] xbuffer = new byte[(buffer.Length * ((tf) ? (1 / 3) : 3))];

Since 1 / 3 is an integer division, it returns 0.And you are declaring xbuffer with the size 0 hence the error.You can fix it by casting one of the operand to a floating point type or using literals.But then you still need to cast the result back to integer.

 byte[] xbuffer = new byte[(int)(buffer.Length * ((tf) ? (1m / 3) : 3))];

The same problem also present in the chunk declaration.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM