Попытка прочитать строки из двоичного файла

Вот простая программа, которую я сделал, просто пытаясь записать пару переменных в двоичный файл, а затем прочитать его обратно.

Я пытаюсь понять, как читать строку из двоичного файла. Вот правильно написал. Но каждый раз, когда я пытаюсь его прочитать (в этом примере это 4 байта), результат получается очень странным, что сбивает все с толку. b = "jump", но как бы я ни пытался читать и конвертировать, конечный результат получается каким-то странным. И тогда переменная b, которая читается после нее, тоже оказывается странной.

Как правильно прочитать строку из двоичного файла? В любом случае все мои строки будут иметь фиксированную длину, 15 символов. Есть ли способ сделать это без преобразования в массив символов?

Я также попробовал метод .ReadCharArrays(), а затем toString(), и я все еще не читаю правильные переменные.

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); 

person LeBron23    schedule 13.02.2013    source источник
comment
Возможный дубликат: stackoverflow.com /вопросы/2426190/   -  person Rhexis    schedule 13.02.2013


Ответы (3)


С чего вы взяли, что JUMP занимает 4 байта?

BinaryWriter.Write(строка):

Записывает в этот поток строку с префиксом длины в текущей кодировке BinaryWriter,

person spender    schedule 13.02.2013
comment
Это действительно больше комментарий, не так ли? - person John Saunders; 13.02.2013
comment
На самом деле это указатель на ответ. Я не люблю кормить с ложки. Я собирался добавить, что br.ReadString - правильный API, но поскольку @500 уже сделал это, в этом мало смысла. - person spender; 13.02.2013
comment
Я все еще немного смущен тем, сколько байтов будет одна строка. Я думал, что каждый символ в строке по существу составляет 1 байт, поэтому строка из 8 символов будет 8 байтов и т. д. - person LeBron23; 13.02.2013
comment
Это может быть справедливо для однобайтовой кодировки, такой как ascii. Однако это не относится ко многим символам в других кодировках. В этом случае с UTF8 это, вероятно, 4 байта... но как насчет префикса длины? ты забыл об этом. Добавление поля длины означает, что вам не нужно знать длину строки, прежде чем вы прочитаете ее с помощью BR.ReadString. Понятно? - person spender; 13.02.2013
comment
@ user2066820, насколько я помню, строка записывается как целое число переменной длины для длины, за которой следуют правильно закодированные символы (по умолчанию UTF8), поэтому в случае JUMP она должна быть 5 байтов. - person Alexei Levenkov; 13.02.2013
comment
По-видимому, поле длины, описанное в документах как целое число без знака в кодировке utf7, на самом деле является LEB128: en.wikipedia.org/ вики/LEB128 - person spender; 13.02.2013

Вы должны использовать BinaryReader.ReadString() для чтения строки обратно - ReadBytes считывает массив байтов, и по умолчанию строки являются unicode в .NET.

person 500 - Internal Server Error    schedule 13.02.2013
comment
Спасибо, я не знал, что .ReadString() существует для C#. - person LeBron23; 13.02.2013
comment
+1. @user2066820 user2066820, рассмотрите возможность использования Visual Studio для редактирования файлов CS и обратите внимание на предложения разведки - он должен был показать вам ReadString в качестве опции, когда вы набрали br.Read. - person Alexei Levenkov; 13.02.2013

BinaryReader.ReadString(). Я только что проверил ваш код, и он работает нормально:

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);
person Simon Whitehead    schedule 13.02.2013
comment
Да, это сработало! Теперь просто нужно выяснить, сколько байтов это будет. Короткий — 2 байта. Это важно, потому что позже я буду делать Direct Address (конечно, в более крупном проекте). - person LeBron23; 13.02.2013
comment
@user2066820 user2066820 Вам действительно нужно изобретать новый двоичный формат? В качестве альтернативы вам может быть лучше рассмотреть двоичную сериализацию. - person spender; 13.02.2013