Eu preciso ler [100]byte
para transferir um monte de string
dados.
Como nem todos os string
s têm exatamente 100 caracteres, a parte restante byte array
é preenchida com 0
s.
Se eu converter [100]byte
para string
por string(byteArray[:])
:, os caracteres finais 0
s serão exibidos como ^@^@
s.
Em C o string
cessará 0
, então eu me pergunto qual é a melhor maneira de converter este byte array
para string
nos golang.
^@
show não aparece, mas estaria lá se você testasse no terminal ou algo parecido. A razão para isso é que o Go não para de converter a matriz de bytes em uma cadeia de caracteres quando encontra um 0.len(string(bytes))
no seu exemplo é 5 e não 1. Depende da função de saída, se a cadeia de caracteres é totalmente (com zeros) impressa ou não.string(body)
.Respostas:
Métodos que lêem dados em fatias de bytes retornam o número de bytes lidos. Você deve salvar esse número e, em seguida, usá-lo para criar sua string. Se
n
for o número de bytes lidos, seu código ficará assim:Para converter a string completa, isso pode ser usado:
Isso é equivalente a:
Se, por algum motivo, você não souber
n
, poderá usar obytes
pacote para encontrá-lo, supondo que sua entrada não tenha um caractere nulo incorporado.Ou, como o icza apontou, você pode usar o código abaixo:
fonte
bytes.IndexByte()
pesquisas de uma única embyte
vez debytes.Index()
uma fatia de bytes contendo 1 byte.A respeito?
fonte
string(byteArray[:])
contém^@
caracteresstring(byteArray)
? Por que você precisa copiar a matriz usando[:]
?[:]
matrizes de bytes.Solução simplista:
Não tenho certeza de quão bom é isso.
fonte
Por exemplo,
Resultado:
fonte
O código a seguir está procurando por '\ 0' e, sob as suposições da pergunta, a matriz pode ser considerada classificada, pois todos os que não são '\ 0' precedem todos os '\ 0'. Essa suposição não será válida se a matriz puder conter '\ 0' nos dados.
Encontre a localização do primeiro byte zero usando uma pesquisa binária e depois faça uma fatia.
Você pode encontrar o byte zero como este:
Pode ser mais rápido varrer ingenuamente a matriz de bytes procurando o byte zero, especialmente se a maioria de suas strings for curta.
fonte
[]byte{0}
. Nesse caso,FirstZero()
deve retornar0
para quando o resultado da fatia seria""
, mas, em vez disso, retorna1
e a fatia resulta"\x00"
.Quando você não souber o comprimento exato de bytes diferentes de zero na matriz, poderá cortá-lo primeiro:
fonte
bytes.Trim
pega uma fatia, não uma matriz (você precisariaarr[:]
se arr fosse realmente[100]byte
como a pergunta indica). b)bytes.Trim
é a função errada a ser usada aqui. Para entradas como[]byte{0,0,'a','b','c',0,'d',0}
retornará "abc \ x00d" em vez de "" c) já existe uma resposta correta que usabytes.IndexByte
, a melhor maneira de encontrar o primeiro byte zero.Por que não isso?
fonte
byteArray[:]
desde quebytes.NewBuffer
leva a[]byte
; b) a pergunta dizia que a matriz possui zeros à direita com os quais você não lida; c) se sua variável é uma[]byte
(a única maneira de compilar sua linha), então sua linha é apenas uma maneira lenta de fazerstring(v)
.Use apenas para ajuste de desempenho.
fonte
string
pode ter implicações sérias se posteriormente a fatia de bytes for modificada.string
os valores no Go são definidos para serem imutáveis, nos quais todo o tempo de execução e as bibliotecas do Go se baseiam. Você se teleportará para o meio dos bugs e erros de execução mais misteriosos se seguir esse caminho.Use fatias em vez de matrizes para leitura. por exemplo,
io.Reader
aceita uma fatia, não uma matriz.Use fatias em vez de preenchimento zero.
Exemplo:
fonte
s := a[:n]
ous := string(a[:n])
se você precisar de uma sequência. Sen
não estiver disponível diretamente, deve ser calculado, por exemplo, procurando um byte específico / zero no buffer (matriz), como Daniel sugere.Tentei alguns métodos algumas vezes entrei em pânico:
Mas isso finalmente funcionou.
string(Data[:])
fonte
Embora não seja de alto desempenho, a única solução legível é
Exemplo completo para ter uma matriz de bytes no estilo C:
Exemplo completo para ter uma string de estilo go excluindo os nulos:
Isso aloca uma fatia da fatia de bytes. Portanto, fique de olho no desempenho, se for usado intensamente ou repetidamente.
fonte
Aqui está o código para compactar a matriz de bytes em string
fonte
Aqui está o caminho mais rápido:
fonte
fmt
, é mais rápido fazerfmt.Printf("%s", bytes)
do que usarstring(bytes)
).Eu quando com uma solução recursiva.
fonte
fmt.Println(CToGoString([]byte("ctogo\x00\x00"), "") == "ctogo")
deve imprimirtrue
, ele imprimefalse
.[100]byte
mas a[]byte
e não remove'\x00'
bytes. Sua velocidade (depende da entrada) é mais lenta por ordem de magnitude múltipla em comparação com a velocidade da resposta aceita.