我创建了一个帮助程序,将切片中的所有数据写入Write
类型,但它非常详细且容易出错。我想知道是否有更好的方法可以忽略ErrorKind::Interrupted
(来自EINTR
)。
fn _write_all<OutputType> (w : &mut OutputType, buf : &[u8]) -> Result<(), io::Error>
where OutputType: Write {
let mut total_written : usize = 0;
while total_written < buf.len() {
match w.write(&buf[total_written..]) {
Err(e) => {
match e.kind() {
ErrorKind::Interrupted => continue,
_ => return Err(e),
}
},
Ok(cur_written) => {
if cur_written == 0 {
return Err(Error::new(ErrorKind::UnexpectedEof, "Write EOF"));
}
total_written += cur_written;
}
}
}
Ok(())
}
我感觉大多数用户将使用try!
宏而忽略ErrorKind::Interrupted
,并且当程序因为系统忙EINTR
而开始失败时会感到惊讶。
如果有更好的方式来写这个,我会非常渴望听到它。
输入也会出现类似的问题,包括嵌套匹配。
对于记录,RFC 517 (IO / OS Reform)表示write_all
忽略EINTR
个错误,但the documentation for Write::write_all
提到write_all
返回遇到的第一个错误,需要类似的循环如上所述。
答案 0 :(得分:3)
文档错误。如果std::io::Write::write_all
返回std::io::Write::write
,ErrorKind::Interrupted
会重新重试in the source:
fn write_all(&mut self, mut buf: &[u8]) -> Result<()> {
while !buf.is_empty() {
match self.write(buf) {
Ok(0) => return Err(Error::new(ErrorKind::WriteZero,
"failed to write whole buffer")),
Ok(n) => buf = &buf[n..],
Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
Err(e) => return Err(e),
}
}
Ok(())
}