在Rust中从标准输入读取原始字节

9
我正在尝试在Rust中从标准输入读取字节。下面的代码对于由常规字符组成的行完美地工作,但对于没有关联字符的原始字节(例如0xe0),这会导致程序崩溃。 文档指出它将在换行符处终止,但未提及非字符字节的任何问题。
编辑:我实际上错过了它确实说所有字节必须是UTF-8编码-是否有另一个函数可以使用来做到这一点?
    let mut input = String::new();
    io::stdin().read_line(&mut input)
        .ok()
        .expect("Couldn't read line");   

2
从您提供的文档链接中可以看到:“此函数与read_until具有相同的错误语义,如果读取的字节无效,则也会返回错误。” - Warren Weckesser
@WarrenWeckesser 谢谢你,我没注意到这个。不然有没有其他读取字节的替代方法呢? - Unsolved Cypher
2
@UnsolvedCypher:你是否有以换行符分隔的非文本数据?这似乎很奇怪,但如果确实如此,那么你的替代方法是沃伦评论中提到的函数。read_until - Benjamin Lindley
不算太奇怪。比如说,这不就是 HTTP 的工作方式吗? - vidstige
1个回答

9

事实证明,Stdin实现了Read特性,因此我能够使用bytes方法:

for i in io::stdin().bytes() {
    println!("read byte {}", i.unwrap());
}

通过检查每个字节,直到达到所需的字节,就可以跳出这个循环。


我并没有看到这种方法比评论中建议的使用read_until()有任何优势。对于标准输入(stdin),这个答案中的方法可能是可以的,因为在Rust中stdin始终是带缓冲的。但是不要尝试对未缓冲的文件使用此方法——每读取一个字节都会导致系统调用,因此性能会非常糟糕。 - Sven Marnach
@SvenMarnach 这可能只是我在 Rust 上经验不足,但我无法弄清如何在 stdin 上调用 read_until(),我找到的所有示例都是用于从文件或其他缓冲区读取。 - Unsolved Cypher
1
你需要先使用 lock() 锁定标准输入(stdin)。得到的 StdinLock 对象实现了 BufRead,而 read_until() 是该特质(trait)的一个方法。 - Sven Marnach
1
请参阅stdin文档的第二个示例 - Sven Marnach

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接