Преобразование строки в байт [] создает нулевой символ
В этой функции преобразования
public static byte[] GetBytes(string str)
{
byte[] bytes = new byte[str.Length * sizeof(char)];
System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}
byte[] test = GetBytes("abc");
Результирующий массив содержит нулевой символ
test = [97, 0, 98, 0, 99, 0]
И когда мы конвертируем байт [] обратно в строку, результат
string test = "a b c "
Как это сделать, чтобы он не создавал эти нули
Ответы
Ответ 1
Сначала посмотрим, что делает ваш код неправильно. char
- это 16-разрядный (2 байта) в .NET framework. Это означает, что когда вы пишете sizeof(char)
, он возвращает 2
. str.Length
- 1
, так что ваш код будет byte[] bytes = new byte[2]
тем же самым byte[2]
. Поэтому, когда вы используете метод Buffer.BlockCopy()
, вы фактически копируете 2
байты из исходного массива в целевой массив. Это означает, что ваш метод GetBytes()
возвращает bytes[0] = 32
и bytes[1] = 0
, если ваша строка " "
.
Попробуйте вместо Encoding.ASCII.GetBytes()
.
При переопределении в производном классе, кодирует все символы в указанную строку в последовательность байтов.
const string input = "Soner Gonul";
byte[] array = Encoding.ASCII.GetBytes(input);
foreach ( byte element in array )
{
Console.WriteLine("{0} = {1}", element, (char)element);
}
Вывод:
83 = S
111 = o
110 = n
101 = e
114 = r
32 =
71 = G
111 = o
110 = n
117 = u
108 = l
Ответ 2
В действительности .net(по крайней мере для 4.0) автоматически изменяет размер char при сериализации с помощью BinaryWriter
Символы UTF-8 имеют переменную длину (может быть не 1 байт), символы ASCII имеют 1 байт
'ē' = 2 байта
'e' = 1 байт
Его следует учитывать при использовании
BinaryReader.ReadChars(stream)
В случае слова "ēvalds" = размер 7 байтов будет отличаться от "evalds" = 6 bytes
Ответ 3
Попробуйте явно указать Encoding
. Вы можете использовать следующий код для преобразования строки в байты с указанной кодировкой
byte[] bytes = System.Text.Encoding.ASCII.GetBytes("abc");
если вы напечатаете содержимое байтов, вы получите { 97,
98,
99 }
, который не содержит нулей, как в вашем примере
В вашем примере кодировка по умолчанию используется 16 бит на символ. Он может быть наблюдателем, распечатывая результаты
System.Text.Encoding.Unicode.GetBytes("abc"); // { 97, 0, 98, 0, 99, 0 }
Затем, преобразовывая его, вы должны выбрать подходящую кодировку:
string str = System.Text.Encoding.ASCII.GetString(bytes);
Console.WriteLine (str);
Печать "abc"
, как вы могли ожидать
Ответ 4
(97,0) представляет собой Unicode-представление 'a'. Unicode представляет каждый символ в двух байтах. Таким образом, вы не можете удалить нули. Но вы можете изменить кодировку на ASCII. Попробуйте выполнить преобразование строки в байт [].
byte[] array = Encoding.ASCII.GetBytes(input);
Ответ 5
Просто, чтобы устранить путаницу в вашем ответе, тип char типа С# занимает 2 байта. Итак, string.toCharArray() возвращает массив, в котором каждый элемент занимает 2 байта памяти. При копировании в байтовый массив, где каждый элемент занимает 1 байтовое хранилище, происходит потеря данных. Следовательно, нули появляются в результате.
Как было предложено, Encoding.ASCII.GetBytes
- более безопасный вариант использования.