如何在Rust中从文件/流中懒惰地读取多个JSON值?

时间:2019-04-22 16:54:16

标签: json serialization rust

我想一次从Rust中的文件/读取器读取多个JSON对象。不幸的是serde_json::from_reader(...)只会读取到文件结束;似乎没有任何方法可以使用它来读取单个对象或延迟迭代这些对象。

有没有办法做到这一点?使用serde_json是理想的选择,但是如果有其他库,我愿意使用它。

此刻,我将每个对象放在单独的行上并分别进行解析,但我真的不希望这样做。

示例用法

main.rs

use serde_json;

fn main() -> Result<(), Box<dyn std::error::Error>> {
   let stdin = std::io::stdin();
   let stdin = stdin.lock();

   for item in serde_json::iter_from_reader(stdin) {
     println!("Got {:?}", item);
   }

   Ok(())
}

in.txt

{"foo": ["bar", "baz"]} 1 2 [] 4 5 6

示例会话

Got Object({"foo": Array([String("bar"), String("baz")])})
Got Number(1)
Got Number(2)
Got Array([])
Got Number(4)
Got Number(5)
Got Number(6)

1 个答案:

答案 0 :(得分:0)

I wanted to do it in Python时这很痛苦,但是幸运的是,在Rust中,这是事实上的serde_json板条箱的直接支持功能!它并没有作为单个便利函数公开,但是我们只需要从文件/读取器创建a serde_json::Deserializer读取,然后使用其.into_iter()方法获得a StreamDeserializer iterator并产生{{1} }个包含Result JSON值。

serde_json::Value

需要注意的一件事:如果遇到语法错误,则迭代器将开始产生无限数量的错误结果,并且永远不会继续。您需要确保处理循环内部的错误,否则循环将永远不会结束。在上面的代码段中,我们通过使用use serde_json; fn main() -> Result<(), Box<dyn std::error::Error>> { let stdin = std::io::stdin(); let stdin = stdin.lock(); let deserializer = serde_json::Deserializer::from_reader(stdin); let iterator = deserializer.into_iter::<serde_json::Value>(); for item in iterator { println!("Got {:?}", item?); } Ok(()) } 问号运算符来打破循环并从函数中返回第一个?来实现此目的。