Разница в написании строки по сравнению смассив символов с System.IO.BinaryWriter
-
06-07-2019 - |
Вопрос
Я записываю текст в двоичный файл на C # и вижу разницу в количестве записей между записью строки и массива символов.Я использую System.IO.BinaryWriter и просматриваю BinaryWriter.Базовый поток.Длина по мере выполнения записи.Это мои результаты:
using(BinaryWriter bw = new BinaryWriter(File.Open(“data.dat”), Encoding.ASCII))
{
string value = “Foo”;
// Writes 4 bytes
bw.Write(value);
// Writes 3 bytes
bw.Write(value.ToCharArray());
}
Я не понимаю, почему перегрузка строки записывает 4 байта, когда я записываю только 3 символа ASCII.Кто-нибудь может это объяснить?
Решение
Документация для BinaryWriter.Write(string)
указывает, что он записывает в этот поток строку с префиксом длины.Перегрузка для Write(char[])
не имеет такого префикса.
Мне бы казалось, что дополнительные данные - это длина.
Редактировать:
Просто чтобы быть немного более понятным, используйте Reflector .Вы увидите, что в нем есть этот фрагмент кода как часть Write(string)
способ:
this.Write7BitEncodedInt(byteCount);
Это способ кодирования целого числа с использованием минимально возможного количества байтов.Для коротких строк (которые мы будем использовать изо дня в день и которые содержат менее 128 символов) они могут быть представлены одним байтом.Для более длинных строк он начинает использовать больше байтов.
Вот код для этой функции на всякий случай, если вам интересно:
protected void Write7BitEncodedInt(int value)
{
uint num = (uint) value;
while (num >= 0x80)
{
this.Write((byte) (num | 0x80));
num = num >> 7;
}
this.Write((byte) num);
}
После префикса длины с использованием этой кодировки он записывает байты для символов в нужной кодировке.
Другие советы
Из BinaryWriter.Write (строка)
документы :
Записывает строку с префиксом длины в этот поток в текущей кодировке BinaryWriter и продвигает текущую позицию потока в соответствии с используемой кодировкой и конкретными символами, записываемыми в поток . р>
Такое поведение, вероятно, таково, что при чтении файла обратно с использованием BinaryReader
можно определить строку. (Например, 3Foo3Bar6Foobar
может быть проанализирован в строку «Foo», «Bar» и «Foobar», но FooBarFoobar
не может быть.) Фактически, BinaryReader.ReadString
использует именно эту информацию для чтения string
из двоичного файла.
Из BinaryWriter.Write (char [])
документы : р>
Записывает массив символов в текущий поток и увеличивает текущую позицию потока в соответствии с используемой кодировкой и конкретными символами, записываемыми в поток.
Трудно переоценить, насколько исчерпывающими и полезными являются документы по MSDN. Всегда проверяйте их в первую очередь.
Как уже говорилось, BinaryWriter.Write (String) записывает длину строки в поток перед записью самой строки.
Это позволяет BinaryReader.ReadString () знать, какова длина строки.
using (BinaryReader br = new BinaryReader(File.OpenRead("data.dat")))
{
string foo1 = br.ReadString();
char[] foo2 = br.ReadChars(3);
}
Вы смотрели на то, что на самом деле было написано? Я предполагаю, что нулевой терминатор.