Thursday, February 17, 2011

What happens when you just set a Stream position to zero (C#)

This morning I was fixing a few bugs which I had found in HTML Combiner and I noticed a few of my unit tests that loaded configuration files were failing. They were using a MemoryStream object so that they read from a string instead of the file system. The first thing I thought was that it was just a problem reading from a string, and wouldn't happen when reading from an actual file.

Of course then I ran the program and notice that when I loaded the configuration file for my website, my tags were showing up twice. After setting up NUnit to run in visual studio and stepping through the debugger, it was in fact reading the file multiple times.

After spending about an hour wondering what was wrong, I casually glanced at a few links on google about resetting a stream position (which I do at the beginning of the method). Finally, I made it to the StreamReader.DiscardBufferedData example code on the MSDN library website.

If you change the stream position using Seek, the actual position of the buffer is now out of sync. So you have to call DiscardBufferedData in order to force the stream to go to the desired position. After I added this line everything worked once again:

sr.DiscardBufferedData();          // where sr is a StreamReader
sr.BaseStream.Seek(0, SeekOrigin.Begin);

This made me glad that I've been adding unit tests to catch things like this -- I might have overlooked the problem the tests weren't failing. Another similar incident happened a few days ago when a small bug was introduced after I made a change, the bug would result in the build path not being loaded from a configuration file. The actual problem looked pretty innocent, it would have taken time to isolate the cause. However, I was able to catch it because the test failed shortly after I had made the change.

No comments:

Post a Comment