Используя C #, какой самый эффективный метод преобразования строки, содержащей двоичные данные, в массив байтов - PullRequest
2 голосов
/ 16 сентября 2008

Хотя существует 100 способов решения проблемы конверсии, я сосредоточен на производительности.

Предположим, что строка содержит только двоичные данные, что является самым быстрым методом с точки зрения производительности преобразования этих данных в байт [] (не char []) в C #?

Уточнение: это не данные ASCII, а двоичные данные, которые находятся в строке.

Ответы [ 4 ]

4 голосов
/ 16 сентября 2008
3 голосов
/ 16 сентября 2008

Я не уверен, что ASCIIEncoding.GetBytes собирается это делать, потому что он поддерживает только диапазон от 0x0000 до 0x007F .

Вы говорите, что строка содержит только байты. Но строка .NET - это массив символов, а 1 символ - 2 байта (потому что .NET хранит строки как UTF16). Таким образом, вы можете иметь две ситуации для хранения байтов 0x42 и 0x98:

  1. Строка была строкой ANSI и содержала байты и преобразуется в строку Unicode, таким образом байты будут 0x00 0x42 0x00 0x98. (Строка сохраняется как 0x0042 и 0x0098)
  2. Строка была просто байтовым массивом, который вы ввели или только что передали в строку, и таким образом стали следующими байтами 0x42 0x98. (Строка хранится как 0x9842)

В первой ситуации результат будет 0x42 и 0x3F (ascii для "B?"). Вторая ситуация приведет к 0x3F (ascii для "?"). Это логично, потому что символы находятся вне допустимого диапазона ASCII, и кодер не знает, что делать с этими значениями.

Так что мне интересно, почему это строка с байтами?

  • Может быть, он содержит байт, закодированный в виде строки (например, Base64 )?
  • Может быть, вам следует начать с массива char или байтового массива?

Если у вас действительно есть ситуация 2, и вы хотите извлечь из нее байты, вы должны использовать вызов UnicodeEncoding.GetBytes . Потому что это вернет 0x42 и 0x98.

Если вы хотите перейти от массива char к байтовому массиву, самый быстрый способ - это Marshaling. Но это не очень хорошо, и использует двойную память.

public Byte[] ConvertToBytes(Char[] source)
{
    Byte[] result = new Byte[source.Length * sizeof(Char)];
    IntPtr tempBuffer = Marshal.AllocHGlobal(result.Length);
    try
    {
        Marshal.Copy(source, 0, tempBuffer, source.Length);
        Marshal.Copy(tempBuffer, result, 0, result.Length);
    }
    finally
    {
        Marshal.FreeHGlobal(tempBuffer);
    }
    return result;
}
0 голосов
/ 16 сентября 2008

Если вы хотите перейти от строки к двоичным данным, вы должны знать, какую кодировку использовали для преобразования двоичных данных в строку, в первую очередь . В противном случае вы можете не получить правильные двоичные данные. Таким образом, наиболее эффективным способом является, вероятно, GetBytes () для подкласса Encoding (например, UTF8Encoding), но вы должны точно знать, какая кодировка.

Комментарий Кента Бугаарта по первоначальному вопросу довольно хорошо подводит итог. ;]

0 голосов
/ 16 сентября 2008

В C # нет такой вещи , как строка ASCII! Строки всегда содержат UTF-16. Неосознание этого приводит к множеству проблем. Тем не менее, методы, упомянутые ранее, работают, потому что они рассматривают строку в кодировке UTF-16 и преобразуют символы в символы ASCII.

/ РЕДАКТИРОВАТЬ в ответ на уточнение: как двоичные данные попали в строку? Строки не должны содержать двоичные данные (для этого используйте byte[]).

...