Golang:以带符号16位整数读取缓冲输入 [英] Golang: Read buffered input as signed 16bit ints

查看:183
本文介绍了Golang:以带符号16位整数读取缓冲输入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试读取带符号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)
    }
    如果错误:= 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:

  1. Can I preformat the byte stream into a buffered int16 array?
  2. 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 []bytes, there's no way to substitute that with []int16, or pre-format that as int16s, 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆