2

Here is a simple program I made just trying to write a couple variables to a binary file, and then reading it back.

I'm trying to figure out how to read a string from a binary file. It wrote it correctly. But every time I try to read it(In this example it's 4 bytes), the result comes out really weird, which throws everything off. b = "jump", yet no matter how I try to read and convert, the end result turns out to something weird. And then variable b, which is read after it, also turns out weird.

What is the proper way to read a string from a binary file? All my strings are going to be fixed length anyways, 15 characters. Is there a way to do it without converting to a char array?

I also tried the .ReadCharArrays() method, and then toString(), and I'm still not reading the correct variables.

string path = ".//..//..//..//";

FileStream mfs = new FileStream(path + "test.bin", FileMode.OpenOrCreate, FileAccess.ReadWrite);
BinaryReader br = new BinaryReader(mfs);
BinaryWriter bw = new BinaryWriter(mfs);

short a = 2;
short b = 3;
string c = "JUMP";
bw.Write(a);
bw.Write(c);
bw.Write(b);

Console.WriteLine("Done writing to binary file");
br.BaseStream.Seek(0, SeekOrigin.Begin); //Apprantly you have to seek to beginning

a = br.ReadInt16();
c = br.ReadBytes(4).toString();
b = br.ReadInt16();

Console.WriteLine(""+a);
Console.WriteLine(""+c);
Console.WriteLine("");
Console.WriteLine("" +b); 
Lee Taylor
  • 7,761
  • 16
  • 33
  • 49
LeBron23
  • 185
  • 1
  • 7
  • Possible duplicate of: http://stackoverflow.com/questions/2426190/how-to-read-file-binary-in-c – Rhexis Feb 13 '13 at 02:00

3 Answers3

2

What makes you think that "JUMP" occupies 4 bytes?

BinaryWriter.Write(string):

Writes a length-prefixed string to this stream in the current encoding of the BinaryWriter,

Community
  • 1
  • 1
spender
  • 117,338
  • 33
  • 229
  • 351
  • 2
    This is really more of a comment, isn't it? – John Saunders Feb 13 '13 at 02:01
  • Actually, it's a pointer to the answer. I don't like to spoonfeed. I was going to add that br.ReadString is the right api, but as @500 has done so already there's little point. – spender Feb 13 '13 at 02:02
  • I'm still a bit confused on how many bytes one string would be though. I thought each character in the string is essentially 1 byte, so an 8 char string would be 8 bytes, etc. – LeBron23 Feb 13 '13 at 02:19
  • That might hold true for single byte encoding such as ascii. It's not the case for many chars in other encodings though. In this case with UTF8, it probably is 4 bytes... but what about the length prefix? you forgot about that. By adding a length field, it means that you don't have to know the length of the string before you read it with BR.ReadString. Got it? – spender Feb 13 '13 at 02:28
  • @user2066820, as far as I remember the string is written as is variable length integer for length followed by properly encoded characters (default UTF8), so in case of "JUMP" it should be 5 bytes. – Alexei Levenkov Feb 13 '13 at 02:31
  • Apparently, the length field described in the docs as utf7 encoded unsigned integer is actually LEB128: http://en.wikipedia.org/wiki/LEB128 – spender Feb 13 '13 at 02:42
2

You should use BinaryReader.ReadString() to read the string back in - ReadBytes reads an array of bytes and by default strings are unicode in .NET.

  • Thanks, I did not know .ReadString() existed for C#. – LeBron23 Feb 13 '13 at 02:18
  • 2
    +1. @user2066820, consider using Visual Studio to edit CS files and paying attention to intellisence suggestions - it should have shown you ReadString as an option when you've typed "br.Read". – Alexei Levenkov Feb 13 '13 at 02:29
2

BinaryReader.ReadString(). I just tested your code and it appears to work fine:

a = br.ReadInt16();
string d = br.ReadString(); // store in another variable just to be sure..
b = br.ReadInt16();

Console.WriteLine("" + a);
Console.WriteLine("" + d); // JUMP
Console.WriteLine("");
Console.WriteLine("" + b);
Simon Whitehead
  • 63,300
  • 9
  • 114
  • 138
  • 1
    Yea it did work! Now just need to figure out how many bytes it would be. A short is 2 bytes. This is important because later I will be doing Direct Address(in a bigger project of course). – LeBron23 Feb 13 '13 at 02:20
  • @user2066820 Do you really need to invent a new binary format? It might be better for you to look at binary serialization as an alternative. – spender Feb 13 '13 at 02:34