fmt.Scan或者fmt.Scanf可以从标准输入中读取数据,也可以自己实现一个类似的功能
package main import ( _"errors" "fmt" "io" "os" "syscall" "time" "bytes" _"os/exec" "github.com/docker/docker/pkg/term" ) func main() { Stdin() } func Stdin() { var in io.Reader in = os.NewFile(uintptr(syscall.Stdin), "/dev/stdin") _,ok:= term.GetFdInfo(in) if ok { fmt.Println("Is terminal \n") } reader := bytes.NewBuffer(make([]byte, 10)) for { data, _:= reader.ReadFrom(in) //很奇怪为什么一直阻塞在这里 fmt.Printf("read from stdin %v \n", data) time.Sleep(2 * time.Second) } }
阻塞在ReadFrom那里,可以看看ReadFrom的具体实现
func (b *Buffer) ReadFrom(r io.Reader) (n int64, err error) { b.lastRead = opInvalid // If buffer is empty, reset to recover space. if b.off >= len(b.buf) { b.Truncate(0) } //因为没有读到标准输出的EOF,所以一直在读 for { if free := cap(b.buf) - len(b.buf); free < MinRead { // not enough space at end newBuf := b.buf if b.off+free < MinRead { // not enough space using beginning of buffer; // double buffer capacity newBuf = makeSlice(2*cap(b.buf) + MinRead) } copy(newBuf, b.buf[b.off:]) b.buf = newBuf[:len(b.buf)-b.off] b.off = 0 } m, e := r.Read(b.buf[len(b.buf):cap(b.buf)]) b.buf = b.buf[0 : len(b.buf)+m] n += int64(m) if e == io.EOF { break } if e != nil { return n, e } } return n, nil // err is EOF, so return nil explicitly }
标准输入设备(stdin)怎么输入EOF??
打印出EOF这个宏 , 值为-1。
但是如果直接输入 -1 ,系统会认为这是两个字符 - 和 1。
其实输入CRTL+D可以算EOF
有疑问加站长微信联系(非本文作者)