valsidalv
valsidalv

Reputation: 821

StringBuilder Silent Error when Appending Lines

I'm reading from multiple log files and appending the lines to a StringBuilder object. However, some of the lines have funky characters and this causes the StringBuilder to silently fail. I believe it appends the last line (with the offending characters) but does not append any lines at all after that. No exception is thrown... either I am incorrectly using StringBuilder or this is a bug.

I display the contents of the StringBuilder in a textbox at the end of the operation. This is at the end of my current output (yes, it is sanitized...):

[2556 0903 141433250 ram] 8 GB of RAM
[2556 0903 141433250 cpu] wicked fast CPU!
[2556 0903 141433640 xyz] a�b��������k'�

There should be more output after that last log line. When I debug this line-by-line in Visual Studio, nothing happens when I reach the Append() line after that last log - it gets hit but the string does not get modified (it doesn't even turn red in the Locals window as variables do when their value changes). Very strange behaviour!

Below is the relevant segment of my code. You'll see I have two StringBuilder objects: one builds a string of the database from which I pull metadata from (odbcResultsRaw), and the other builds the actual contents using the metadata to find the appropriate log file (odbcResultsNice). fileReaders is a Dictionary of a custom StreamReaders:

OdbcDataReader dbReader = com.ExecuteReader();
while (dbReader.Read())
{
   string fileName = dbReader[1].ToString(); // source file
   int fileLineNum = int.Parse(dbReader[2].ToString());  // line number in source file

   // grab the appropriate StreamReader, not important...
   CustomStreamReader fileReader = fileReaders[fileName];
   string line = String.Empty;

   // navigate to the correct line, not important...
   while (fileReaders[fileName].currentLineNum < fileLineNum)
   {
      // read in line from log file; where the magic happens
      line = fileReaders[fileName].ReadLine();
      fileReaders[fileName].currentLineNum++;
   }
   odbcResultsRaw.AppendLine(fileName + ", " + fileLineNum.ToString());
   odbcResultsNice.AppendLine(line);
}

odbcResultsRaw always works; that is trivial. But odbcResultsNice will die as described above. In the end I may have 7,000 lines for odbcResultsRaw but only a few hundred for odbcResultsNice - indication that the code does continue to run, at least.

I believe I have two options: 'fix' the StringBuilder (or understand if I'm using it in an unintended manner) or figure out how to ignore offending lines. Would like to know your thoughts and suggestions.

Note: I cannot know when I will encounter a file or line with these characters. I'm not sure if they're of a different encoding or just random garbage.

Upvotes: 1

Views: 802

Answers (1)

valsidalv
valsidalv

Reputation: 821

Thanks to Hans Passant for pointing me in the right direction. I've fixed up the code by adding this right after the while statement (found on http://www.csharp411.com/cleanstripremove-binary-characters-from-c-string/):

foreach (char c in line)
{
   odbcResultsNice.Append(Char.IsControl(c) ? ' ' : c);  // replace bad char with space
}

And the last line was changed just to add a linebreak:

odbcResultsNice.AppendLine();

My output now looks like this:

[2556 0903 141433250 ram] 8 GB of RAM
[2556 0903 141433250 cpu] wicked fast CPU!
[2556 0903 141433640 xyz]  a�b��������k'� 7�����H_ ���-v �L`�oƙ*=
[2556 0903 141434000 gfx] it can play crysis
...

You can see the spaces in the xyz log line, which replace the offending characters.

Upvotes: 0

Related Questions