【问题标题】:How I can I lazily read multiple JSON values from a file/stream in Rust?如何从 Rust 中的文件/流中懒惰地读取多个 JSON 值?
【发布时间】:2019-09-11 20:34:40
【问题描述】:

我想从 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)

【问题讨论】:

标签: json serialization rust


【解决方案1】:

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

use serde_json; // 1.0.39

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(())
}

需要注意的一点:如果遇到语法错误,迭代器将开始产生无限序列的错误结果,并且永远不会继续前进。您需要确保处理循环内部的错误,否则循环将永远不会结束。在上面的 sn-p 中,我们通过使用? 问号运算符来打破循环并从我们的函数返回第一个serde_json::Result::Err

【讨论】:

  • 留下评论只是为了感谢杰里米来到这里生活这个版本的问题,他在 8 年前提出了这个问题,并拯救了我的本科生。谢谢杰里米。保持安全
  • 它仍然读取整个文件并在循环内一次打印整个文件内容。您是否尝试过使用格式正确的 JSON 文件?
猜你喜欢
  • 2011-10-16
  • 1970-01-01
  • 2012-08-13
  • 2021-03-04
  • 1970-01-01
  • 2016-02-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多