Как преобразовать байтовый буфер, содержащий нули, в строку - PullRequest
1 голос
/ 20 февраля 2012

У меня есть байтовый массив в качестве ввода.Это должно быть двоичное представление стандарта, соответствующего HTML UTF8.Да, но в большинстве случаев только.Иногда он также содержит встроенные нули (\x0 символ или NUL).Это не под моим контролем.Мне нужно преобразовать этот байтовый массив в строку.

Пробовал до сих пор:

  • Очевидно, использование StreamReader или TextReader не работает, так как останавливается при нажатии на первуюNUL
  • Encoding.UTF8.GetString тоже не работает - также останавливается на первом NUL

Что сработало, но довольно нелегко:

   mynewarray = myoldarray.Where( x => x!=0).ToArray();
   var output = Encoding.UTF8.GetString(mynewarray);

Есть ли более элегантный способ сделать это исключительным при создании нового байтового массива, пропуская символы NUL, а затем использовать одно из приведенных выше решений?Массив байтов может быть довольно большим, более 2-4 Мб ... MSDN сообщает, что строки могут содержать встроенные NUL, но не сообщает, как лучше всего обрабатывать такие строки.

Ответы [ 3 ]

1 голос
/ 20 февраля 2012

Ваша строка уже верна. Он будет содержать NUL символов. Но когда вы используете строку с включенными NUL символами, вы получите все виды проблем.

Encoding.UTF8.GetString не останавливается на \ 0, как вы видите в моем примере.

Посмотрите, что произойдет, когда я выведу такую ​​строку:

  var text = new byte[]{65, 65, 0, 65};
  var s = Encoding.UTF8.GetString(text);
  Console.WriteLine("len is: " + s.Length + " chars");
  Console.WriteLine("text: '" + s + "'");      
  Console.WriteLine("this line doesn't appear because NUL was sent to console");

вывод:

len is: 4 chars
text: 'AA
0 голосов
/ 20 февраля 2012

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

Отличная математика указателядля быстрой итерации по массивам и у вас есть полный контроль над тем, как далеко вы хотите продвинуть свои указатели памяти (таким образом, это "небезопасно").Это означает, что вы можете потреблять / пропускать любого персонажа по желанию.Для этой цели я регулярно использую оптимизированные буферы + небезопасный код в c #.

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

0 голосов
/ 20 февраля 2012

Используйте перегрузку GetString, которая принимает начальный индекс и количество байтов для декодирования

var output = Encodeing.UTF8.GetString(mynewarray, 0, mynewarray.Length);
...