我正试图在Golang中读取Stdin,因为我正在尝试为Erlang实现驱动程序。我有以下代码:
package main
import (
"fmt"
"os"
"bufio"
"time"
)
func main() {
go func() {
stdout := bufio.NewWriter(os.Stdin)
p := []byte{121,100,125,'\n'}
stdout.Write(p)
}()
stdin := bufio.NewReader(os.Stdin)
values := make([]byte,4,4)
for{
fmt.Println("b")
if read_exact(stdin) > 0 {
stdin.Read(values)
fmt.Println("a")
give_func_write(values)
}else{
continue
}
}
}
func read_exact(r *bufio.Reader) int {
bits := make([]byte,3,3)
a,_ := r.Read(bits)
if a > 0 {
r.Reset(r)
return 1
}
return -1
}
func give_func_write(a []byte) bool {
fmt.Println("Yahu")
return true
}
但似乎永远无法达到give_func_write
。我尝试在2秒后开始使用goroutine写入标准输入来测试它。
我在这里缺少什么?
这一行r.Reset(r)
。这有效吗?我试图实现的只是从文件的开头重新开始读取。还有更好的方法吗?
修改
在玩完之后,我发现代码卡在a,_ := r.Read(bits)
函数中的read_exact
答案 0 :(得分:6)
我想我需要有一个协议,我发送一个\ n到 使输入工作,同时在阅读时将其丢弃
不,你没有。 Stdin只有在绑定到终端时才会进行行缓冲。您可以运行自己的计划prog < /dev/zero
或cat file | prog
。
bufio.NewWriter(os.Stdin).WRITE(p)的
您可能不想写信给stdin
。有关详细信息,请参阅“Writing to stdin and reading from stdout”。
嗯,对我来说,你想要达到的目标并不是特别清楚。我假设您只想通过固定大小的块读取stdin
的数据。请使用io.ReadFull。或者,如果要使用缓冲区,可以使用Reader.Peak或Scanner来确保可以使用特定数量的字节。我已更改您的程序以演示io.ReadFull
的使用情况:
package main
import (
"fmt"
"io"
"time"
)
func main() {
input, output := io.Pipe()
go func() {
defer output.Close()
for _, m := range []byte("123456") {
output.Write([]byte{m})
time.Sleep(time.Second)
}
}()
message := make([]byte, 3)
_, err := io.ReadFull(input, message)
for err == nil {
fmt.Println(string(message))
_, err = io.ReadFull(input, message)
}
if err != io.EOF {
panic(err)
}
}
您可以轻松地将其拆分为两个程序并以此方式进行测试。只需将input
更改为os.Stdin
。