in, out := bufio.NewReader(os.Stdin), bufio.NewWriter(os.Stdout)
for {
c, err := in.ReadByte()
if err == io.EOF {
break
}
out.WriteByte(c)
}
我想从stdin流中逐字节读取。与Read
方法ReadByte
不同,它似乎不会返回io.EOF
。如果已读取所有字节,我该怎么办?
答案 0 :(得分:3)
这不是Reader.ReadByte()
实施的问题,也不是bufio.NewReader()
的问题。
请参阅此示例以证明它:
buf := bytes.NewBufferString("Hello World!\n")
in := bufio.NewReader(buf)
for {
c, err := in.ReadByte()
if err == io.EOF {
break
}
fmt.Print(string(c))
}
运行时,上面打印
Hello World!
并且正确终止。
您的问题是os.Stdin
。从中读取具体来源。如果它是您的终端,则从中读取只是阻止并且不报告io.EOF
。请参阅此示例以证明它:
in := bufio.NewReader(os.Stdin)
for {
fmt.Println("Reading.")
c, err := in.ReadByte()
if err == io.EOF {
break
}
fmt.Print(string(c))
}
它的输出是:
Reading.
没有任何反应。没有新的迭代,它被阻止。现在,如果您输入一行并按 Enter ,例如输入Go!
,输出将为:
Go!
GReading.
oReading.
!Reading.
Reading.
再次等待新的输入。如您所见,每行都有数据输入/可用。这是您的终端所做的:当您输入行时,它不会发送到os.Stdin
。按 Enter 后,整行将被输入并可从os.Stdin
获得。这就是我们看到的:输入Go!
的每个字母和换行符。我们看到每次迭代都打印了Reading.
文本。使用输入后,再次阻止in.ReadByte()
,等待新输入。它不会报告io.EOF
。
现在尝试以下操作:创建一个文件,例如a.txt
并将其修改为一行:Go!
和换行符。现在将此文件作为程序的标准输入提供:
go run play.go < a.txt
运行它我们会看到:
Reading.
GReading.
oReading.
!Reading.
Reading.
Reading.
它终止,所以它的工作原理!这是有效的,因为这次os.Stdin
的来源不是您的控制台/终端,而是文件的内容,一旦消耗,尝试从os.Stdin
读取将正确报告io.EOF
。