Reputation: 13
I am making a simple program where at the start of the file I want to write the size of the following section. When I open the file in notepad, the size is correctly written. When I try to parse it in the program, however, I get the "Input string was not in a correct format." exception. Here is the code I use to write it to the file:
StreamWriter writer = new StreamWriter(stream, ENCODING);
int headerSize = ENCODING.GetByteCount(Header);
writer.Write(headerSize.ToString(HEADER_SIZE_FORMAT));
writer.Write(Header);
writer.Close();
Here is the code I use to try and read it from the file (that throws the exception):
FileStream stream = new FileStream(path, FileMode.Open);
int headerSizeLength = ENCODING.GetByteCount((0).ToString(HEADER_SIZE_FORMAT)) + ENCODING.GetByteCount("1");
byte[] headerSizeArray = new byte[headerSizeLength];
stream.Read(headerSizeArray, 0, headerSizeLength);
System.Windows.Forms.MessageBox.Show(ENCODING.GetString(headerSizeArray));
int headerSize = Convert.ToInt32(ENCODING.GetString(headerSizeArray));
(I close the stream properly down from there, but this does not matter because the exception is thrown on the last line I quoted here)
The value of ENCODING is currently Encoding.Unicode. The value of HEADER_SIZE_FORMAT is currently "0000".
I initially wanted to write the size in hex format ("X8" I think) but encountered the same problem with parsing and changed it to the usual decimal format...
The MessageBox that shows me the string before I attempt to parse it appears to show me the correct number - 0188, matching the format and all.
I added the extra character length to the buffer length because before it it read one character less than it should have, according to MessageBox and what I saw in Notepad. This is probably a symptom of the same problem but I can't understand what's wrong )=
ADDITIONALLY: when I hardcode the number instead of trying to parse it from file, the rest of it appears to parse into string properly...
Upvotes: 1
Views: 146
Reputation: 216323
You could really simplify your code with
string buffer = File.ReadAllText(path);
string header = buffer.Substring(0, 4); // 4 hardcoded based on the write.ToString("0000")
int headerSize = Convert.ToInt32(header);
Console.WriteLine(headerSize);
The problem with your actual code is that you read the file in binary mode. This means that your read also the first 3 bytes that are the UTF8 preamble. Of course these bytes are no convertible in a valid numeric string and thus you get the conversion error.
If you insist in reading your file in binary mode then you need to account for this UTF8 Preamble
FileStream stream = new FileStream(path, FileMode.Open);
// Count the bytes of your header_size_format plus the UTF8 preamble length
int headerSizeLength = ENCODING.GetByteCount(HEADER_SIZE_FORMAT) +
ENCODING.GetPreamble().Length;
byte[] headerSizeArray = new byte[headerSizeLength];
// Read preamble and your header
stream.Read(headerSizeArray, 0 , headerSizeLength);
// Start to convert the byte array in a string just after the preamble bytes.
int headerSize = Convert.ToInt32(ENCODING.GetString(headerSizeArray,
ENCODING.GetPreamble().Length,
HEADER_SIZE_FORMAT.Length));
It is important to say that this situation happens just because, when you create your file in your first example, you explicitily ask the UTF8 encoding in the StreamWriter constructor.
If you omit that parameter the file will be created without the UTF8 preamble and thus the reading need to be changed. All in all, I think you should avoid to read your file in binary mode and use directly the File.Read or a StreamReader letting the framework do its job in returning the strings from the file.
Upvotes: 4