将字节数组转换为string的最佳方法是什么?

我需要读取[100]byte来传输一串string数据。

由于不是所有的string都精确到100,所以byte array的其余部分用0填充。

如果我将[100]bytestringstring(byteArray[:]) ,则string(byteArray[:]) 0将显示为^@^@ s。

在C中string将终止于0 ,所以我不知道什么是巧妙地传输byte arraystring的最佳方式。

将数据读入字节片段的方法返回读取的字节数。 您应该保存该号码,然后用它来创build您的string。 n是读取的字节数,你的代码看起来像这样:

 s := string(byteArray[:n]) 

如果由于某种原因,你没有n ,你可以使用字节包来find它,假设你的input中没有空字符。

 n := bytes.Index(byteArray, []byte{0}) 

或者正如icza指出的,你可以使用下面的代码:

 n := bytes.IndexByte(byteArray, 0) 

关于什么?

 s := string(byteArray[:]) 

简单的解决scheme:

 str := fmt.Sprintf("%s", byteArray) 

我不确定这是如何高性能的。

例如,

 package main import "fmt" func CToGoString(c []byte) string { n := -1 for i, b := range c { if b == 0 { break } n = i } return string(c[:n+1]) } func main() { c := [100]byte{'a', 'b', 'c'} fmt.Println("C: ", len(c), c[:4]) g := CToGoString(c[:]) fmt.Println("Go:", len(g), g) } 

输出:

 C: 100 [97 98 99 0] Go: 3 abc 

下面的代码正在寻找'\ 0',在这个问题的假设下,数组可以被认为是sorting的,因为所有非'\ 0'都在'\ 0'之前。 如果数组中可以包含“\ 0”,这个假设就不会成立。

使用二进制search查找第一个零字节的位置,然后切片。

你可以find像这样的零字节:

 package main import "fmt" func FirstZero(b []byte) int { min, max := 0, len(b) for { if min + 1 == max { return max } mid := (min + max) / 2 if b[mid] == '\000' { max = mid } else { min = mid } } return len(b) } func main() { b := []byte{1, 2, 3, 0, 0, 0} fmt.Println(FirstZero(b)) } 

只是天真地扫描字节数组寻找零字节可能会更快,特别是如果大部分string都很短。

 package main import ( "fmt" "reflect" "unsafe" ) func BytesToString(b []byte) string { bh := (*reflect.SliceHeader)(unsafe.Pointer(&b)) sh := reflect.StringHeader{bh.Data, bh.Len} return *(*string)(unsafe.Pointer(&sh)) } func StringToBytes(s string) []byte { sh := (*reflect.StringHeader)(unsafe.Pointer(&s)) bh := reflect.SliceHeader{sh.Data, sh.Len, 0} return *(*[]byte)(unsafe.Pointer(&bh)) } func main() { b := []byte{'b', 'y', 't', 'e'} s := BytesToString(b) fmt.Println(s) b = StringToBytes(s) fmt.Println(string(b)) } 
  • 使用切片而不是arrays进行阅读。 例如io.Reader接受一个切片,而不是一个数组。

  • 使用切片而不是零填充。

例:

 buf := make([]byte, 100) n, err := myReader.Read(buf) if n == 0 && err != nil { log.Fatal(err) } consume(buf[:n]) // consume will see exact (not padded) slice of read data 

为什么不呢?

 bytes.NewBuffer(byteArray).String() 

我什么时候用recursion解决scheme。

 func CToGoString(c []byte, acc string) string { if len(c) == 0 { return acc } else { head := c[0] tail := c[1:] return CToGoString(tail, acc + fmt.Sprintf("%c", head)) } } func main() { b := []byte{some char bytes} fmt.Println(CToGoString(b, "")) }