Используя C #, каков наиболее эффективный метод преобразования строки, содержащей двоичные данные, в массив байтов
Вопрос
Хотя существует 100 способов решить проблему конверсии, я сосредотачиваюсь на производительности.
Учитывая, что строка содержит только двоичные данные, каков самый быстрый с точки зрения производительности метод преобразования этих данных в byte[] (не char[]) в C #?
Разъяснение:Это не данные в формате ASCII, а двоичные данные, которые находятся в строке.
Решение
Я не уверен, что ASCIIEncoding.getBytes собирается это сделать, потому что он поддерживает только диапазон от 0x0000 до 0x007F.
Вы сообщаете, что строка содержит только байты.Но строка .NET - это массив символов, а 1 символ равен 2 байтам (потому что .NET хранит строки как UTF16).Таким образом, у вас могут быть либо две ситуации для хранения байтов 0x42, либо 0x98:
- Строка была строкой ANSI и содержала байты и преобразуется в строку Unicode, таким образом, байты будут равны 0x00 0x42 0x00 0x98.(Строка сохраняется как 0x0042 и 0x0098)
- Строка была просто массивом байтов, который вы ввели или просто получили в строку и, таким образом, стали следующими байтами 0x42 0x98.(Строка хранится как 0x9842)
В первой ситуации результатом было бы 0x42 и 0x3F (ascii для "B?").Вторая ситуация привела бы к 0x3F (ascii для "?").Это логично, потому что символы находятся за пределами допустимого диапазона ascii, и кодировщик не знает, что делать с этими значениями.
Поэтому мне интересно, почему это строка с байтами?
- Возможно, он содержит байт, закодированный в виде строки (например Base64)?
- Может быть, вам следует начать с массива символов или массива байтов?
Если у вас действительно есть ситуация 2, и вы хотите извлечь из нее байты, вам следует использовать UnicodeEncoding.Получаем байты позвони.Потому что это вернет 0x42 и 0x98.
Если вы хотите перейти от массива символов к массиву байтов, самым быстрым способом будет маршалинг..Но это не очень приятно и использует двойную память.
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;
}
Другие советы
Есть ничего подобного нет как строка ASCII в C #!Струны всегда содержит UTF-16.Непонимание этого приводит к множеству проблем.Тем не менее, методы, упомянутые ранее, работают, потому что они рассматривают строку в кодировке UTF-16 и преобразуют символы в символы ASCII.
/ РЕДАКТИРОВАТЬ в ответ на уточнение:как двоичные данные попали в строку?Строки не должны содержать двоичных данных (используйте byte[]
за это).
Если вы хотите перейти от строки к двоичным данным, в первую очередь вы должны знать, какая кодировка была использована для преобразования двоичных данных в строку.В противном случае вы можете получить неверные двоичные данные.Итак, наиболее эффективным способом, вероятно, является getBytes() для подкласса Encoding (такого как UTF8Encoding), но вы должны точно знать, в какой кодировке.
Комментарий Кента Бугарта к первоначальному вопросу довольно хорошо подводит итог.;]