Golang:以带符号16位整数读取缓冲输入 [英] Golang: Read buffered input as signed 16bit ints
问题描述
我正在尝试读取带符号16位整数(wav格式)的缓冲流,但bufio.Read方法只接受一组字节。我的问题是一个2分的:
- 我可以将字节流预先格式化为一个缓冲的int16数组吗?
-
如果我不能,将字节数组后处理为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)
}
如果错误:= cmd.Start(); err!= nil {
log.Fatal(err)
}
//someapp输出带符号16位整数(小端))
buf:= make ([] byte,0,4 * 1024)
for {
n,err:= r.Read(buf [:cap(buf)])//r.Read只接受类型[]字节
buf = buf [:n]
如果n == 0 {
if err == nil {
continue
}
if err == io.EOF {
break
}
log.Fatal(err)
}
log.Printf(%x \ n ,buf)
//在此处理buf
如果err!= nil&& err!= io.EOF {
log.Fatal(err)
}
}
}
使用IO时,您总是使用 []字节
s,没有办法用 [] int16
来替换它,或者预格式化为 int16
s,它总是一个字节流。
你可以看看 编码/二进制
包来解码此流。
//获取第一个uint16作为我
i:= binary.LittleEndian.Uint16(buf [:2])
然后您可以根据需要遍历buf。
您也可以使用 binary.Read
直接从 io.Reader
中读取。
var i uint16
for {
err:= binary.Read(r,binary.LittleEndian, & i)
如果err!= nil {
log.Println(err)
break
}
fmt.Println(i)
}
可能值得注意的是需要做的简单工作。每个 uint16
都是通过以下方式创建的:
func(littleEndian)Uint16(b []字节)uint16 {
return uint16(b [0])| uint16(b [1])<8
}
I am trying to read a buffered stream of signed 16 bit integers (wav format), but the bufio.Read method only accepts an array of bytes. My question is a 2-parter:
- Can I preformat the byte stream into a buffered int16 array?
If I can't, whats the best way of post-processing the byte array into int16 array? My initial thought is to use tmp arrays and keep pushing/processing them, but I was curious if there was a more idiomatic way of doing this?
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) } } }
When working with IO, you always work with []byte
s, there's no way to substitute that with []int16
, or pre-format that as int16
s, it's always a stream of bytes.
You can look at the encoding/binary
package to decode this stream.
// to get the first uint16 as i
i := binary.LittleEndian.Uint16(buf[:2])
You can then iterate through the buf as needed.
You can also use binary.Read
to read directly from the io.Reader
.
var i uint16
for {
err := binary.Read(r, binary.LittleEndian, &i)
if err != nil {
log.Println(err)
break
}
fmt.Println(i)
}
It may worth noting the simplicity of what needs to be done. Each uint16
is created via:
func (littleEndian) Uint16(b []byte) uint16 {
return uint16(b[0]) | uint16(b[1])<<8
}
这篇关于Golang:以带符号16位整数读取缓冲输入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!