英文:
How to read input from console in a non blocking way with Go?
问题
所以我有:
import (
"bufio"
"os"
)
//...
var reader = bufio.NewReader(os.Stdin)
str, err := reader.ReadString('\n')
但是reader.ReadString('\n')
会阻塞执行。我想以非阻塞的方式读取输入。是否可以使用bufio
包或Go的任何其他标准库包从os.Stdin
实现非阻塞缓冲输入?
英文:
So I have:
import (
"bufio"
"os"
)
//...
var reader = bufio.NewReader(os.Stdin)
str, err := reader.ReadString('\n')
But reader.ReadString('\n')
is blocking execution. I would like to read input in a non blocking way. Is it possible to achieve non blocking buffered input from os.Stdin
using bufio
package or any other std lib package from Go?
答案1
得分: 12
一般来说,Go语言中没有非阻塞IO API的概念。你可以通过使用goroutines来实现相同的功能。
以下是一个示例,由于Playground不允许使用stdin,所以这里模拟了stdin。
package main
import "fmt"
import "time"
func main() {
ch := make(chan string)
go func(ch chan string) {
/* Uncomment this block to actually read from stdin
reader := bufio.NewReader(os.Stdin)
for {
s, err := reader.ReadString('\n')
if err != nil { // Maybe log non io.EOF errors, if you want
close(ch)
return
}
ch <- s
}
*/
// Simulating stdin
ch <- "A line of text"
close(ch)
}(ch)
stdinloop:
for {
select {
case stdin, ok := <-ch:
if !ok {
break stdinloop
} else {
fmt.Println("Read input from stdin:", stdin)
}
case <-time.After(1 * time.Second):
// Do something when there is nothing read from stdin
}
}
fmt.Println("Done, stdin must be closed")
}
你可以在这里查看示例代码。
英文:
In general there isn't a concept of non-blocking IO APIs in Go. You accomplish the same thing by using goroutines.
Here's an example on Play, stdin is simulated since play doesn't allow for it.
package main
import "fmt"
import "time"
func main() {
ch := make(chan string)
go func(ch chan string) {
/* Uncomment this block to actually read from stdin
reader := bufio.NewReader(os.Stdin)
for {
s, err := reader.ReadString('\n')
if err != nil { // Maybe log non io.EOF errors, if you want
close(ch)
return
}
ch <- s
}
*/
// Simulating stdin
ch <- "A line of text"
close(ch)
}(ch)
stdinloop:
for {
select {
case stdin, ok := <-ch:
if !ok {
break stdinloop
} else {
fmt.Println("Read input from stdin:", stdin)
}
case <-time.After(1 * time.Second):
// Do something when there is nothing read from stdin
}
}
fmt.Println("Done, stdin must be closed")
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论