Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to read input from console in a non blocking way with Go?

Tags:

io

go

nonblocking

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?

like image 518
marcio Avatar asked Dec 19 '22 09:12

marcio


1 Answers

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")
}
like image 148
David Budworth Avatar answered Dec 25 '22 22:12

David Budworth