从stdin接收二进制数据,发送到Go中的通道

0 binary stdin channel go

所以我有以下测试Go代码,它设计用于通过stdin读取二进制文件,并将读取的数据发送到通道,然后进一步处理.在我在这里给出的版本中,它只从stdin中读取前两个值,尽管就显示问题而言这很好.

package main

import (
    "fmt"
    "io"
    "os"
)

func input(dc chan []byte) {
    data := make([]byte, 2)
    var err error
    var n int
    for err != io.EOF {
        n, err = os.Stdin.Read(data)
        if n > 0 {
            dc <- data[0:n]
        }
    }
}

func main() {
    dc := make(chan []byte, 1)
    go input(dc)
    fmt.Println(<-dc)
}
Run Code Online (Sandbox Code Playgroud)

为了测试它,我首先使用go build构建它,然后使用命令向它发送数据 -

./inputtest < data.bin
Run Code Online (Sandbox Code Playgroud)

我目前用来测试的数据只是使用openssl命令创建的随机二进制数据.

我遇到的问题是它错过了Stdin的第一个值,只给出了第二个和更大的值.我认为这与通道有关,因为移除通道的相同脚本会生成正确的数据.有没有人遇到过这个?例如,运行此命令时,我得到以下输出 -

./inputtest < data.bin
[36 181]
Run Code Online (Sandbox Code Playgroud)

我应该得到 -

./inputtest < data.bin
[72 218]
Run Code Online (Sandbox Code Playgroud)

(二进制数据在两个实例中都是相同的.)

Dus*_*tin 5

你在每次读取时都要覆盖你的缓冲区,并且你有一个通道缓冲区,所以每次通道中都有空间时你就会丢失数据.

尝试这样的事情(没有经过测试,写在平板电脑上等等):

func input(dc chan []byte) {
    defer close(dc)
    for {
        data := make([]byte, 2)
        n, err := os.Stdin.Read(data)
        if n > 0 {
            dc <- data[0:n]
        }
    }
}
Run Code Online (Sandbox Code Playgroud)