我正在尝试读取带符号的16位整数(wav格式)的缓冲流,但是bufio.Read方法只接受一个字节数组。我的问题是2人:
如果我不能,那么将字节数组后处理成int16数组的最佳方法是什么?我最初的想法是使用tmp数组并继续推送/处理它们,但我很好奇是否有更惯用的方法呢?
package main
import (
"bufio"
"io"
"log"
"os/exec"
)
func main() {
app := "someapp"
cmd := exec.Command(app)
stdout, err := cmd.StdoutPipe()
r := bufio.NewReader(stdout)
if err != nil {
log.Fatal(err)
}
if err := cmd.Start(); err != nil {
log.Fatal(err)
}
//"someapp" outputs signed 16bit integers (little endian))
buf := make([]byte, 0, 4*1024)
for {
n, err := r.Read(buf[:cap(buf)]) //r.Read only accepts type []byte
buf = buf[:n]
if n == 0 {
if err == nil {
continue
}
if err == io.EOF {
break
}
log.Fatal(err)
}
log.Printf("%x\n", buf)
//process buf here
if err != nil && err != io.EOF {
log.Fatal(err)
}
}
}
答案 0 :(得分:3)
使用IO时,您始终使用[]byte
,无法将其替换为[]int16
,或者将其格式化为int16
s,它& #39; s总是一个字节流。
您可以查看encoding/binary
包来解码此流。
// to get the first uint16 as i
i := binary.LittleEndian.Uint16(buf[:2])
然后,您可以根据需要迭代buf。
您也可以使用binary.Read
直接从io.Reader
阅读。
var i uint16
for {
err := binary.Read(r, binary.LittleEndian, &i)
if err != nil {
log.Println(err)
break
}
fmt.Println(i)
}
值得注意的是需要做的事情的简单性。每个uint16
都是通过以下方式创建的:
func (littleEndian) Uint16(b []byte) uint16 {
return uint16(b[0]) | uint16(b[1])<<8
}
答案 1 :(得分:1)
您可以使用encoding/binary.Read
直接从您的阅读器填充[]int16
,但从技术上讲,您的第一个问题的答案仍然是否定(请查看binary.Read
的来源,它会读取数据首先到[]byte
。