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

huangapple go评论75阅读模式
英文:

Golang: Read buffered input as signed 16bit ints

问题

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

  1. 我能否将字节流预格式化为带缓冲的int16数组?
  2. 如果不能,将字节数组后处理为int16数组的最佳方法是什么?我最初的想法是使用临时数组并不断推送/处理它们,但我想知道是否有更符合惯用方式的方法?
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"输出有符号16位整数(小端序)
	buf := make([]byte, 0, 4*1024)

	for {
		n, err := r.Read(buf[:cap(buf)]) // r.Read只接受[]byte类型
		buf = buf[:n]
		if n == 0 {
			if err == nil {
				continue
			}
			if err == io.EOF {
				break
			}
			log.Fatal(err)
		}

		log.Printf("%x\n", buf)
		// 在这里处理buf

		if err != nil && err != io.EOF {
			log.Fatal(err)
		}
	}
}
英文:

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)
     	    }
         }
     }
    

答案1

得分: 4

在处理输入输出(IO)时,你总是使用[]byte,无法用[]int16替代它,也无法预先将其格式化为int16,它始终是一串字节流。

你可以查看encoding/binary包来解码这个流。

// 获取第一个uint16作为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
}
英文:

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, &amp;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])&lt;&lt;8
}

答案2

得分: 1

你可以使用encoding/binary.Read直接从读取器中填充[]int16,尽管从技术上讲,对于你的第一个问题,答案仍然是否定的(请检查binary.Read的源代码,它首先将数据读取到[]byte中)。

英文:

You can use encoding/binary.Read to fill an []int16 directly from your reader, although technically the answer to your first question is still no (check the source of binary.Read, it reads the data to a []byte first).

huangapple
  • 本文由 发表于 2015年3月10日 02:18:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/28949063.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定