Остановка bufio.Scanner с остановкой канала - PullRequest
1 голос
/ 01 апреля 2020

Я пишу что-то, что читает строки из os.Stdin, используя bufio.Scanner, например:

for s.scanner.Scan() {
  line := s.scanner.Text()
  // process line
}

Это выполняется в программе, и я хочу иметь возможность остановить его, когда chan struct{} закрывается Однако, когда Scan блокируется, пока не появится другая строка, я в растерянности, как остановить его, если больше нет ввода, он будет блокироваться бесконечно.

Может кто-нибудь указать мне правую направление здесь?

1 Ответ

2 голосов
/ 01 апреля 2020

Создав еще одно косвенное обращение и игнорируя базовый, мы можем остановиться.

// actual reading, converts input stream to a channel
func readUnderlying(lines chan interface{}) {
    s := bufio.NewScanner(os.Stdin)
    for s.Scan() {
        lines <- s.Text()
    }
    lines <- s.Err()
}

func read(stop chan struct{}) {
    input := make(chan interface{}) // input stream
    go readUnderlying(input) // go and read
    for {
        select { // read or close
        case lineOrErr := <-input:
            fmt.Println(lineOrErr)
        case <-stop:
            return
        }
    }
}

func main() {
    stop := make(chan struct{})
    go read(stop)

    // wait some to simulate blocking
    time.Sleep(time.Second * 20) // it will print what is given
    close(stop)
    time.Sleep(time.Second * 20) // stopped so no more processing
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...