Как избежать буферизации на stdin и stdout?

При чтении из std::io::stdin() вход буферизуется до тех пор, пока не будет встречен EOF. Я бы хотел обработать строки по мере их поступления, а не ждать, пока все буферизуется.

Для функции оболочки bar, которая выполняется echo bar каждую секунду навсегда, я тестирую это с помощью bar | thingy. Он ничего не печатает, пока не будет ^C.

Вот что я сейчас работаю с:

use std::io;
use std::io::timer;
use std::time::Duration;

fn main() {
    let mut reader = io::stdin();
    let interval = Duration::milliseconds(1000);

    loop {
        match reader.read_line() {
            Ok(l) => print!("{}", l),
            Err(_) => timer::sleep(interval),
        }
    }
}

Ответы

Ответ 1

При чтении из std:: io:: stdin() вход буферизуется до тех пор, пока не встретится EOF

Почему ты так говоришь? Ваш код работает так, как вам хочется. Если я скомпилирую его и запустил:

$ ./i
hello
hello

goodbye
goodbye

yeah!
yeah!

Первая из каждой пары строк - это ввод в терминал и попадание в нее (это то, что ищет read_line). Вторая - это то, что выводит ваша программа.

Err(_) => timer::sleep(interval)

Это плохая идея - когда вход закрыт (например, с помощью ^D), ваша программа не заканчивается.

Edit

Я создал script bar:

#!/bin/bash

set -eu

i=0

while true; do
    echo $i
    sleep 1
done

И затем запустил его:

./bar | ./i
0

0

0

Ваша программа продолжает работать.