Преобразование строки в байт [] создает нулевой символ

В этой функции преобразования

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 - более безопасный вариант использования.