在golang从stdin读取

时间:2015-03-15 13:07:20

标签: go

我正试图在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

1 个答案:

答案 0 :(得分:6)

  

我想我需要有一个协议,我发送一个\ n到   使输入工作,同时在阅读时将其丢弃

不,你没有。 Stdin只有在绑定到终端时才会进行行缓冲。您可以运行自己的计划prog < /dev/zerocat file | prog

  

bufio.NewWriter(os.Stdin).WRITE(p)的

您可能不想写信给stdin。有关详细信息,请参阅“Writing to stdin and reading from stdout”。

嗯,对我来说,你想要达到的目标并不是特别清楚。我假设您只想通过固定大小的块读取stdin的数据。请使用io.ReadFull。或者,如果要使用缓冲区,可以使用Reader.PeakScanner来确保可以使用特定数量的字节。我已更改您的程序以演示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