Разница в написании строки по сравнению смассив символов с System.IO.BinaryWriter

StackOverflow https://stackoverflow.com/questions/1014727

Вопрос

Я записываю текст в двоичный файл на 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);
}

Вы смотрели на то, что на самом деле было написано? Я предполагаю, что нулевой терминатор.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top