Golang:将缓冲输入读取为带符号的16位整数

时间:2015-03-09 18:18:16

标签: go buffer wav

我正在尝试读取带符号的16位整数(wav格式)的缓冲流,但是bufio.Read方法只接受一个字节数组。我的问题是2人:

  1. 我可以将字节流预先格式化为缓冲的int16数组吗?
  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)
            }
        }
    }
    

2 个答案:

答案 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