Преобразование из байта [] в строку - PullRequest
3 голосов
/ 21 августа 2009

У меня есть следующий код:

using (BinaryReader br = new BinaryReader(
       File.Open(FILE_PATH, FileMode.Open, FileAccess.ReadWrite)))
{
    int pos = 0;
    int length = (int) br.BaseStream.Length;

    while (pos < length)
    {
        b[pos] = br.ReadByte();
        pos++;
    }

    pos = 0;
    while (pos < length)
    {
        Console.WriteLine(Convert.ToString(b[pos]));
        pos++;
    }
}

FILE_PATH - это константная строка, содержащая путь к читаемому двоичному файлу. Двоичный файл представляет собой смесь целых чисел и символов. Целые числа составляют 1 байт каждый, и каждый символ записывается в файл как 2 байта.

Например, файл содержит следующие данные:

1ХЕЛЛО, КАК ТЫ 45, ТЫ СМОТРИШЬСЯ БОЛЬШОЙ // и так далее

Обратите внимание: каждое целое число связано со строкой символов, следующей за ним. Таким образом, 1 ассоциируется с «HELLO HOW A YOU», а 45 - с «YOU LACING GREAT» и т. Д.

Теперь бинарный файл написан (я не знаю почему, но я должен с этим смириться), так что '1' займет всего 1 байт, а 'H' (и другие символы) занимают 2 байта каждый.

Итак, вот что на самом деле содержит файл:

0100480045..и так далее Вот разбивка:

01 - первый байт для целого числа 1 0048 - это 2 байта для «H» (H - 48 в шестнадцатеричном формате) 0045 - это 2 байта для 'E' (E = 0x45)

и так далее .. Я хочу, чтобы моя консоль выводила из этого файла удобочитаемый формат: чтобы я напечатал «Привет, как дела», а затем «45, ты выглядишь великолепно» и так далее ...

Что я делаю правильно? Есть ли более простой / эффективный способ? Моя строка Console.WriteLine (Convert.ToString (b [pos])); ничего не делает, но печатает целочисленное значение, а не фактический символ, который я хочу. Это нормально для целых чисел в файле, но тогда как мне прочитать символы?

Любая помощь будет принята с благодарностью. Спасибо

Ответы [ 3 ]

8 голосов
/ 21 августа 2009

Я думаю, что вы ищете Encoding.GetString .

Поскольку ваши строковые данные состоят из 2-х байтовых символов, вы можете вывести свою строку следующим образом:

for (int i = 0; i < b.Length; i++)
{
  byte curByte = b[i];

  // Assuming that the first byte of a 2-byte character sequence will be 0
  if (curByte != 0)
  { 
    // This is a 1 byte number
    Console.WriteLine(Convert.ToString(curByte));
  }
  else
  { 
    // This is a 2 byte character. Print it out.
    Console.WriteLine(Encoding.Unicode.GetString(b, i, 2));

    // We consumed the next character as well, no need to deal with it
    //  in the next round of the loop.
    i++;
  }
}
2 голосов
/ 21 августа 2009

Вы можете использовать String System.Text.UnicodeEncoding.GetString (), который принимает массив byte [] и создает строку.

Я нашел эту ссылку очень полезной

Обратите внимание, что это не то же самое, что просто слепое копирование байтов из массива byte [] в кусок памяти и вызов его в виде строки. Метод GetString () должен проверять байты и запрещать недопустимые суррогаты, например.

0 голосов
/ 21 августа 2009
using (BinaryReader br = new BinaryReader(File.Open(FILE_PATH, FileMode.Open, FileAccess.ReadWrite)))
{    
   int length = (int)br.BaseStream.Length;    

   byte[] buffer = new byte[length * 2];
   int bufferPosition = 0;

   while (pos < length)    
   {        
       byte b = br.ReadByte();        
       if(b < 10)
       {
          buffer[bufferPosition] = 0;
          buffer[bufferPosition + 1] = b + 0x30;
          pos++;
       }
       else
       {
          buffer[bufferPosition] = b;
          buffer[bufferPosition + 1] = br.ReadByte();
          pos += 2;
       }
       bufferPosition += 2;       
   }    

   Console.WriteLine(System.Text.Encoding.Unicode.GetString(buffer, 0, bufferPosition));

}

...