Necesito leer [100]byte
para transferir un montón de string
datos.
Debido a que no todos los string
s tienen exactamente 100 caracteres de largo, la parte restante del mismo byte array
se rellena con 0
s.
Si convierto [100]byte
a string
by:, string(byteArray[:])
los 0
s de cola se muestran como ^@^@
s.
En la C string
se terminará con 0
, por lo que me pregunto ¿cuál es la mejor manera de convertir esta byte array
a string
en Golang.
^@
no se muestra, pero hubiera estado allí si lo probaras en la terminal o algo similar. La razón de esto es que Go no deja de convertir la matriz de bytes en una cadena cuando encuentra un 0.len(string(bytes))
en su ejemplo es 5 y no 1. Depende de la función de salida, si la cadena está totalmente (con ceros) impresa o no.string(body)
.Respuestas:
Los métodos que leen datos en segmentos de bytes devuelven el número de bytes leídos. Debe guardar ese número y luego usarlo para crear su cadena. Si
n
es el número de bytes leídos, su código se vería así:Para convertir la cadena completa, esto se puede usar:
Esto es equivalente a:
Si por alguna razón no lo sabe
n
, puede usar elbytes
paquete para encontrarlo, suponiendo que su entrada no tenga un carácter nulo incrustado.O como señaló icza, puede usar el siguiente código:
fuente
bytes.IndexByte()
qué búsquedas para un solo enbyte
lugar debytes.Index()
con un segmento de bytes que contiene 1 byte.¿Qué pasa?
fuente
string(byteArray[:])
contiene^@
caracteresstring(byteArray)
? ¿Por qué necesitas copiar la matriz usando[:]
?[:]
, para los conjuntos de bytes, sí.Solución simplista:
Sin embargo, no estoy seguro de cuán eficiente es esto.
fuente
Por ejemplo,
Salida:
fuente
El siguiente código busca '\ 0', y bajo los supuestos de la pregunta, la matriz se puede considerar ordenada ya que todos los que no son '\ 0' preceden a todos '\ 0'. Esta suposición no se mantendrá si la matriz puede contener '\ 0' dentro de los datos.
Encuentre la ubicación del primer byte cero usando una búsqueda binaria, luego corte.
Puede encontrar el byte cero de esta manera:
Puede ser más rápido escanear ingenuamente la matriz de bytes en busca del byte cero, especialmente si la mayoría de sus cadenas son cortas.
fuente
[]byte{0}
. En este caso,FirstZero()
debería regresar0
así cuando el resultado de corte sería""
, pero en su lugar, regresa1
y los resultados de corte en"\x00"
.Cuando no conoce la longitud exacta de bytes no nulos en la matriz, puede recortarla primero:
fuente
bytes.Trim
toma un segmento, no una matriz (lo que necesitaríaarr[:]
si arr es realmente a[100]byte
como dice la pregunta). b)bytes.Trim
es la función incorrecta para usar aquí. Para una entrada como[]byte{0,0,'a','b','c',0,'d',0}
esta devolverá "abc \ x00d" en lugar de "" c) ya existe una respuesta correcta que utilizabytes.IndexByte
, la mejor manera de encontrar el primer byte cero.¿Por qué no esto?
fuente
byteArray[:]
ya quebytes.NewBuffer
toma a[]byte
; b) la pregunta decía que la matriz tiene ceros finales con los que no se trata; c) si, en cambio, su variable es a[]byte
(la única forma en que se compilará su línea), entonces su línea es solo una forma lenta de hacerlostring(v)
.Solo se usa para ajuste de rendimiento.
fuente
string
puede tener serias implicaciones si luego se modifica el segmento de bytes.string
los valores en Go se definen como inmutables, sobre los cuales se basan todo el tiempo de ejecución y las bibliotecas de Go. Te teletransportarás a la mitad de los errores y errores de tiempo de ejecución más misteriosos si sigues este camino.Use rebanadas en lugar de matrices para leer. por ejemplo,
io.Reader
acepta un segmento, no una matriz.Use rebanado en lugar de cero relleno.
Ejemplo:
fuente
s := a[:n]
os := string(a[:n])
si necesita una cadena. Sin
no está directamente disponible, debe calcularse, por ejemplo, buscando un byte específico / cero en el búfer (matriz) como sugiere Daniel.Probé algunos métodos pocas veces me entró el pánico:
Pero esto finalmente funcionó.
string(Data[:])
fuente
Aunque no es extremadamente eficiente, la única solución legible es
Ejemplo completo para tener una matriz de bytes de estilo C:
Ejemplo completo para tener una cadena de estilo ir excluyendo los nulos:
Esto asigna una porción de porción de bytes. Por lo tanto, vigile el rendimiento si se usa en gran medida o repetidamente.
fuente
Aquí está el código para comprimir la matriz de bytes a una cadena
fuente
Aquí está la forma más rápida:
fuente
fmt
, es más rápido hacerfmt.Printf("%s", bytes)
que usarstring(bytes)
).Yo cuando con una solución recursiva.
fuente
fmt.Println(CToGoString([]byte("ctogo\x00\x00"), "") == "ctogo")
debe imprimirtrue
, imprimefalse
.[100]byte
sino a[]byte
, y no elimina'\x00'
bytes. Su velocidad (depende de la entrada) es más lenta en múltiples órdenes de magnitud en comparación con la velocidad de la respuesta aceptada.