从标准输入接收二进制数据,在Go中发送到通道。

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

Receiving binary data from stdin, sending to channel in 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)
}

为了测试它,我首先使用go build进行构建,然后使用以下命令向其发送数据:

./inputtest < data.bin

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

我遇到的问题是它会漏掉Stdin的第一个值,只给出第二个及更大的值。我认为这与通道有关,因为删除通道的相同脚本会产生正确的数据。有人遇到过这种情况吗?例如,当运行以下命令时,我会得到以下输出:

./inputtest < data.bin
[36 181]

而我应该得到:

./inputtest < data.bin
[72 218]

(两种情况下的二进制数据是相同的。)

英文:

so I have the following test Go code which is designed to read from a binary file through stdin, and send the data read to a channel, (where it would then be processed further). In the version I've given here, it only reads the first two values from stdin, although that's fine as far as showing the problem is concerned.

package main

import (
	&quot;fmt&quot;
	&quot;io&quot;
	&quot;os&quot;
)

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 &gt; 0 {
			dc &lt;- data[0:n]
		}
	}
}

func main() {
	dc := make(chan []byte, 1)
	go input(dc)
	fmt.Println(&lt;-dc)
}

To test it, I first build it using go build, and then send data to it using the command-

./inputtest &lt; data.bin

The data I am using currently to test is just random binary data created using the openssl command.

The problem I am having is that it misses the first values from Stdin, and only gives the second and greater values. I think this is to do with the channel, as the same script with the channel removed produces the correct data. Has anyone come across this before? For example, I get the following output when running this command-

./inputtest &lt; data.bin
[36 181]

Whereas I should be getting-

./inputtest &lt; data.bin
[72 218]

(The binary data is the same in both instances.)

答案1

得分: 5

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

尝试像这样做(未经测试,使用平板电脑编写等):

import "os"

func input(dc chan []byte) error {
	defer close(dc)
	for {
		data := make([]byte, 2)
		n, err := os.Stdin.Read(data)
		if n > 0 {
			dc <- data[0:n]
		}
		if err != nil {
			return err
		}
	}
	return nil
}
英文:

You're overwriting your buffer on every read and you've got a channel buffer, so you'll lose data every time there's space in the channel.

Try something like this (not tested, written on tablet, etc...):

import &quot;os&quot;

func input(dc chan []byte) error {
	defer close(dc)
	for {
		data := make([]byte, 2)
		n, err := os.Stdin.Read(data)
		if n &gt; 0 {
			dc &lt;- data[0:n]
		}
		if err != nil {
			return err
		}
	}
	return nil
}

huangapple
  • 本文由 发表于 2013年11月25日 00:17:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/20176796.html
匿名

发表评论

匿名网友

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

确定