Мне нужно прочитать, [100]byte
чтобы передать кучу string
данных.
Поскольку не все string
s имеют длину в 100 символов, оставшаяся часть byte array
дополняется символом 0
s.
Если я преобразую [100]byte
в string
:, string(byteArray[:])
хвосты 0
s отображаются как ^@^@
s.
В C string
закончится по 0
, так интересно , что это лучший способ , чтобы преобразовать это byte array
в string
в Golang.
^@
не показывается, но он был бы там, если бы вы проверили его в терминале или что-то подобное. Причина этого в том, что Go не прекращает преобразование массива байтов в строку, когда находит 0len(string(bytes))
в вашем примере, а не 1. Это зависит от функции вывода, полностью ли (с нулями) напечатана строка или нет.string(body)
.Ответы:
Методы, которые читают данные в байтовые фрагменты, возвращают количество прочитанных байтов. Вы должны сохранить это число и затем использовать его для создания вашей строки. Если
n
это число прочитанных байтов, ваш код будет выглядеть так:Для преобразования полной строки это может быть использовано:
Это эквивалентно:
Если по какой-то причине вы не знаете
n
, вы можете использоватьbytes
пакет, чтобы найти его, предполагая, что в вашем вводе нет встроенного нулевого символа.Или, как указал icza, вы можете использовать код ниже:
источник
bytes.IndexByte()
поиск по одному,byte
а не поbytes.Index()
байтовому срезу, содержащему 1 байт.Что о?
источник
string(byteArray[:])
содержит^@
символыstring(byteArray)
? Почему вам нужно скопировать массив с помощью[:]
?[:]
, для байтовых массивов вы это делаете.Упрощенное решение:
Я не уверен, насколько это эффективно.
источник
Например,
Вывод:
источник
Следующий код ищет «\ 0», и в соответствии с предположениями вопроса массив можно считать отсортированным, поскольку все не-\ 0 предшествуют всем «\ 0». Это предположение не будет выполнено, если массив может содержать '\ 0' в данных.
Найдите местоположение первого нулевого байта с помощью двоичного поиска, а затем среза.
Вы можете найти нулевой байт следующим образом:
Может быть быстрее просто наивно сканировать байтовый массив в поисках нулевого байта, особенно если большинство ваших строк короткие.
источник
[]byte{0}
. В этом случаеFirstZero()
должен возвращать0
так, когда результат нарезки будет""
, но вместо этого он возвращает1
и результаты нарезки в"\x00"
.Если вы не знаете точную длину ненулевых байтов в массиве, вы можете сначала обрезать ее:
источник
bytes.Trim
берет срез, а не массив (вам нужно,arr[:]
если arr на самом деле является a,[100]byte
как указано в вопросе). б)bytes.Trim
это неправильная функция для использования здесь. Для ввода, подобного[]byte{0,0,'a','b','c',0,'d',0}
ему, будет возвращено «abc \ x00d» вместо «» c) там уже есть правильный ответ, который используетbytes.IndexByte
лучший способ найти первый нулевой байт.Почему не это?
источник
byteArray[:]
так какbytes.NewBuffer
принимает[]byte
; б) вопрос о том, что массив имеет конечные нули, с которыми вы не имеете дело; c) если вместо этого ваша переменная - это[]byte
(единственный способ, которым ваша строка будет компилироваться), то ваша строка - это просто медленный способ выполненияstring(v)
.Используйте только для настройки производительности.
источник
string
может иметь серьезные последствия, если позже модифицировать байтовый фрагмент.string
значения в Go определены как неизменяемые, на которых основывается вся среда выполнения Go и библиотеки. Если вы пойдете по этому пути, вы будете телепортироваться в самые загадочные ошибки и ошибки времени выполнения.Используйте фрагменты вместо массивов для чтения. например,
io.Reader
принимает срез, а не массив.Используйте нарезку вместо заполнения нулями.
Пример:
источник
s := a[:n]
или,s := string(a[:n])
если вам нужна строка. Еслиn
он не доступен напрямую, он должен быть рассчитан, например, путем поиска определенного / нулевого байта в буфере (массиве), как предлагает Даниэль.Я попробовал несколько методов, несколько раз я впал в панику:
Но это наконец сработало.
string(Data[:])
источник
Хотя и не очень производительный, единственное читаемое решение
Полный пример наличия байтового массива в стиле C:
Полный пример, чтобы иметь строку стиля go, исключая нули:
Это выделяет кусочек кусочка байтов. Так что следите за производительностью, если она используется интенсивно или многократно.
источник
Вот код для сжатия байтового массива в строку
источник
Вот более быстрый способ:
источник
fmt
это быстрее,fmt.Printf("%s", bytes)
чем использоватьstring(bytes)
).Я когда с рекурсивным решением.
источник
fmt.Println(CToGoString([]byte("ctogo\x00\x00"), "") == "ctogo")
должен распечататьtrue
, он печатаетfalse
.[100]byte
а a[]byte
и не снимает'\x00'
байты. Его скорость (зависит от ввода) медленнее на несколько порядков по сравнению со скоростью принятого ответа.