lost in FileStream hell

MtAiryDude

New member
Joined
Jan 16, 2023
Messages
2
Programming Experience
10+
I'm pulling my hair out over the following code, which always throws the exception "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 (Parameter 'count')" when it executes the Read() method of the FileStream object fs. When I trace through the code, BytesToRead has the value 16 (which is correct, and matches the number of elements in the iv array). The file named in FilePath exists, is not being accessed by any other process, and is much longer than 16 bytes. What am I doing wrong?

C#:
                string FilePath = @"C:\Data\Encryption\Test.txt";
                // intervening code omitted
                using (FileStream fs = new FileStream (FilePath, FileMode.Open)) //open encrypted file
                {
                    using (Aes aes = Aes.Create()) //create new instance of Aes class
                    {
                        byte[] iv = new byte[aes.IV.Length - 1];
                        int BytesToRead = aes.IV.Length;
                        int BytesRead = 0;
                        //read initialization vector from beginning of file
                        while (BytesToRead > 0)
                        {
                            int n = fs.Read(iv, BytesRead, BytesToRead);  //THIS LINE ALWAYS THROWS AN EXCEPTION
                            // balance of while loop omitted
                        }
                      // balance of code omitted
                    }
 
Last edited by a moderator:
Welcome. In there future please put your code in code tags to help preserve indents.

Moving to C# General. This does not like like a VS.NET issue.
 
Look closer at your line 7. Your array is smaller than the number of bytes you are trying to read.
 
Have you maybe come from a VB background? In VB, you specify the upper bound when creating an array, while C# requires that you specify the length. This:
C#:
byte[] iv = new byte[aes.IV.Length - 1];
looks like how you'd do it in VB.

Note that you would have seen this for yourself if you had debugged the code properly. You should have set a breakpoint and stepped through the code and examined the state at each step and you'd have seen that iv.Length was less than BytesToRead, exactly as the error message is telling you.
 
Actually, I did set a breakpoint and step through the code, many times. And yes, I do come from a VB background (and was translating this code to C# for a presentation to a group of mostly C# coders) so I see now the problem was my confusion over how array declarations differ between VB and C#. I'd assumed that all .Net languages enforce the same rules around arrays, but clearly that's not the case.
 
Actually, I did set a breakpoint and step through the code, many times.
You stated this to us:
When I trace through the code, BytesToRead has the value 16 (which is correct, and matches the number of elements in the iv array).
but it appears that you never actually confirmed that, despite the error message stating explicitly that that was the issue. You know what they say about assuming. ;)
 
BytesRead and BytesToRead should have a lowercase b

If you want to fully fill an array when reading from a stream, make the array to the size you want and instruct Read() to read to its length

C#:
var buf = new byte[16];
var bytesRead = da.Read(buf, 0, buf.Length);

Try to avoid having unnecessary one time variables, or variables for variables' sake
 
it appears that you never actually confirmed that,
yeah but maybe coming from a VB background they were looking at something that said "iv, byte[15]" and thinking "15 is the last index on a zero start array, it must have 16 elements".. perhaps easy to see what we can't see past
 
yeah but maybe coming from a VB background they were looking at something that said "iv, byte[15]" and thinking "15 is the last index on a zero start array, it must have 16 elements".. perhaps easy to see what we can't see past
Maybe so, but my point is that if you're going to state that the length of an array is equal to some value, you probably ought to look at the Length of that array. There's an Immediate window in VS for a reason. I appreciate that it's easy to overlook such things but, when an error message is telling you that explicitly, probably best to check explicitly.
 
To me, the question is if you allocate a 16 element array, what does the Visual Studio debugger show in the Local Variables pane for iv when debugging in C#? Does it show the same thing when debugging in VB.NET? Does VB6 show the same thing as well?
 
Back
Top Bottom