有没有办法检查stdinRust中的数据是否可用,或者是否使用当前可用的数据进行立即返回的读取?
我的目标是能够读取由shell中的光标键产生的输入,该shell被设置为立即返回所有读取数据.例如,相当于:stty -echo -echok -icanon min 1 time 0.
我想一个解决方案是使用ncurses或类似的库,但我想避免任何类型的大依赖.
到目前为止,我只得到阻止输入,这不是我想要的:
let mut reader = stdin();
let mut s = String::new();
match reader.read_to_string(&mut s) {...} // this blocks :(
Run Code Online (Sandbox Code Playgroud)
小智 9
将 OP 的评论转换为答案:
您可以生成一个线程并通过通道发送数据。然后,您可以使用try_recv在主线程中轮询该通道。
use std::io;
use std::sync::mpsc;
use std::sync::mpsc::Receiver;
use std::sync::mpsc::TryRecvError;
use std::{thread, time};
fn main() {
let stdin_channel = spawn_stdin_channel();
loop {
match stdin_channel.try_recv() {
Ok(key) => println!("Received: {}", key),
Err(TryRecvError::Empty) => println!("Channel empty"),
Err(TryRecvError::Disconnected) => panic!("Channel disconnected"),
}
sleep(1000);
}
}
fn spawn_stdin_channel() -> Receiver<String> {
let (tx, rx) = mpsc::channel::<String>();
thread::spawn(move || loop {
let mut buffer = String::new();
io::stdin().read_line(&mut buffer).unwrap();
tx.send(buffer).unwrap();
});
rx
}
fn sleep(millis: u64) {
let duration = time::Duration::from_millis(millis);
thread::sleep(duration);
}
Run Code Online (Sandbox Code Playgroud)
大多数操作系统默认以阻塞方式使用标准输入和输出。难怪 Rust 库取而代之。
要以非阻塞方式从阻塞流中读取,您可能会创建一个单独的线程,以便额外的线程阻塞而不是主线程。检查阻塞文件描述符是否产生一些输入是类似的:产生一个线程,让它读取数据,检查它到目前为止是否产生了任何数据。
这是我使用的一段代码,它具有类似的目标,即交互式处理管道输出,希望可以作为示例。它通过支持try_recv方法的通道发送数据- 允许您检查数据是否可用。
有人告诉我,mio可能用于以非阻塞方式从管道中读取数据,因此您可能也想查看一下。我怀疑将 stdin 文件描述符 (0) 传递给PipeReader::from_fd应该可以正常工作。
| 归档时间: |
|
| 查看次数: |
3964 次 |
| 最近记录: |