无法在Rust中读取子stderr两次



由于某种原因,我无法第二次读取子进程stderr。这是我的工作。

我正在为黄瓜测试生成一个子进程。在第一步中,我生成进程,获取它的stderr,保存它,然后从中读取

pub fn wait_process_output(
reader: &mut BufReader<ChildStderr>,
output: Vec<(String, u16)>,
) -> Result<(), String> {
let mut process_output = String::new();
loop {
match reader.read_line(&mut process_output) {
Err(e) => {
return Err(format!("Unable to read output: {}", e));
}
Ok(_) => {
// processing here
}
};
}
}
pub fn step1(world: &mut TestWorld) {
world.app_handler = Some(
Command::new(&world.app_bin)
.stderr(Stdio::piped())
.spawn()
.unwrap(),
);
let app_stderr = world.app_handler.as_mut().unwrap().stderr.take().unwrap();
world.app_reader = Some(BufReader::new(app_stderr));
wait_process_output(world.app_reader.as_mut().unwrap(), /* expected data */).ok();
}

此代码工作正常:stderr正在按预期读取。

在第三个测试步骤中,我尝试再次读取过程输出:

pub fn step3(world: &mut TestWorld) {
wait_process_output(world.app_reader.as_mut().unwrap(), /* expected data */).ok();
}

这一次reader.read_line无限挂起:没有读取任何内容。我确信子进程会产生一些输出:如果我在相同的条件下单独运行它,我可以看到它。

当我第二次尝试读取BufReader对象时,你能提出一些想法吗?

我找到了解决方案。问题是appstep3开始读取之前产生了一个输出。我认为有某种缓冲区可以用于这种情况,但我似乎错了。因此,我最终使用了以下两种方法来解决我的问题:

pub fn wait_process_output(
receiver: &Receiver<String>,
output: Vec<(String, u16)>,
) -> Result<(), String> {
loop {
match receiver.try_recv() {
// process output
}
}
}
pub fn start_listener(sender: Sender<String>, stream: ChildStderr) {
spawn(move || {
let mut f = BufReader::new(stream);
loop {
let mut buf = String::new();
match f.read_line(&mut buf) {
Ok(_) => {
sender.send(buf).unwrap();
continue;
}
Err(e) => {
println!("Unable to read process stderr: {:?}", e);
break;
}
}
}
});
}

最新更新