rust:读文件报错! stream did not contain valid UTF-8

2019-11-06 09:17:07 +08:00
 guonaihong

读取二进制文件报错

下面的代码可以复现

use std::fs::File;
use std::io::{self, prelude::*, BufReader};

fn main() -> io::Result<()> {
    let file = File::open("./target/debug/foo")?;
    let reader = BufReader::new(file);

    for line in reader.lines() {
        println!("{}", line?);
    }

    Ok(())
}

//输出
//Error: Custom { kind: InvalidData, error: StringError("stream did not contain valid UTF-8") }

能想的解决方法

不使用官方库的函数,实现一个类似 reader.lines 的方法,不过返回 bytes。想问下除了自己手动造轮子有没有现成的方法???

6401 次点击
所在节点    Rust
7 条回复
PeterD
2019-11-06 09:46:41 +08:00
```rust
#[stable(feature = "rust1", since = "1.0.0")]
impl<B: BufRead> Iterator for Lines<B> {
type Item = Result<String>;
```

Lines 用的是 String,不是 [u8]

要读 [u8] 要用 mut [u8; N]

```rust
use std::{fs, io, io::Read};

pub fn main() {
let path = "abc";
let f = fs::File::open(path).unwrap();
let mut buf: [u8; 10] = Default::default();
let mut r = io::BufReader::new(f);
r.read(&mut buf).unwrap();
for i in &buf {
println!("{}", i);
}
}
```
guonaihong
2019-11-06 12:47:02 +08:00
@PeterD 谢谢回答,对于二进制文件,也想每次取一行,如何做呢?
gfreezy
2019-11-06 12:51:28 +08:00
二进制文件理论上没有行的概念。
好像有个库提供了 read_until 的方法。
PeterD
2019-11-06 12:55:04 +08:00
@guonaihong bytes 没有行的概念,如果你想要的是用 b'\n' 来分割“行”,你可以检查读出的 buf 里有没有 b'\n',然后在拼接。
guonaihong
2019-11-06 13:01:28 +08:00
@PeterD ok。没有 std 方法,我先自己造个。谢谢了。。。
gfreezy
2019-11-06 13:25:12 +08:00
guonaihong
2019-11-06 13:55:49 +08:00
@gfreezy 谢了,read_until 可以满足我的需求。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/616721

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX