我如何解析JSON文件?

Vik*_*ton 33 json rust

到目前为止,我的目标是在Rust中解析此JSON数据:

extern crate rustc_serialize;
use rustc_serialize::json::Json;
use std::fs::File;
use std::io::copy;
use std::io::stdout;

fn main() {
    let mut file = File::open("text.json").unwrap();
    let mut stdout = stdout();
    let mut str = &copy(&mut file, &mut stdout).unwrap().to_string();
    let data = Json::from_str(str).unwrap();
}
Run Code Online (Sandbox Code Playgroud)

并且text.json

{
    "FirstName": "John",
    "LastName": "Doe",
    "Age": 43,
    "Address": {
        "Street": "Downing Street 10",
        "City": "London",
        "Country": "Great Britain"
    },
    "PhoneNumbers": [
        "+44 1234567",
        "+44 2345678"
    ]
}
Run Code Online (Sandbox Code Playgroud)

解析它的下一步应该是什么?我的主要目标是获取这样的JSON数据,并从中解析一个密钥,如Age.

Vik*_*ton 26

由Rust社区的许多有用成员解决:

extern crate rustc_serialize;
use rustc_serialize::json::Json;
use std::fs::File;
use std::io::Read;

fn main() {
    let mut file = File::open("text.json").unwrap();
    let mut data = String::new();
    file.read_to_string(&mut data).unwrap();

    let json = Json::from_str(&data).unwrap();
    println!("{}", json.find_path(&["Address", "Street"]).unwrap());
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,rustc_serialize repo表示现在已弃用,以支持https://github.com/serde-rs/json (7认同)

She*_*ter 22

Serde是首选的JSON序列化提供程序.您可以通过多种方式从文件中读取JSON文本.将它作为字符串后,使用serde_json::from_str:

extern crate serde;
extern crate serde_json;

fn main() {
    let the_file = r#"{
        "FirstName": "John",
        "LastName": "Doe",
        "Age": 43,
        "Address": {
            "Street": "Downing Street 10",
            "City": "London",
            "Country": "Great Britain"
        },
        "PhoneNumbers": [
            "+44 1234567",
            "+44 2345678"
        ]
    }"#;

    let json: serde_json::Value =
        serde_json::from_str(the_file).expect("JSON was not well-formatted");
}
Run Code Online (Sandbox Code Playgroud)

您甚至可以使用类似于serde_json::from_reader直接从打开的内容中读取的内容File.

Serde可以用于JSON以外的格式,它可以序列化和反序列化为自定义结构而不是任意集合:

#[macro_use]
extern crate serde_derive;

#[derive(Debug, Deserialize)]
#[serde(rename_all = "PascalCase")]
struct Person {
    first_name: String,
    last_name: String,
    age: u8,
    address: Address,
    phone_numbers: Vec<String>,
}

#[derive(Debug, Deserialize)]
#[serde(rename_all = "PascalCase")]
struct Address {
    street: String,
    city: String,
    country: String,
}
Run Code Online (Sandbox Code Playgroud)
let person: Person = serde_json::from_str(the_file).expect("JSON was not well-formatted");
println!("{:?}", person)
Run Code Online (Sandbox Code Playgroud)

查看Serde网站了解更多详情.


sem*_*267 7

赞成接受的答案(因为它有帮助),但只是添加我的答案,使用@FrickeFresh 引用的广泛使用的serde_json板条箱

假设你foo.json

{
    "name": "Jane",
    "age": 11
}
Run Code Online (Sandbox Code Playgroud)

实施看起来像

extern crate serde;
extern crate json_serde;
#[macro_use] extern crate json_derive;
use std::fs::File;
use std::io::Read;

#[derive(Serialize, Deserialize)]
struct Foo {
    name: String,
    age: u32,
}

fn main() {
   let mut file = File::open("foo.json").unwrap();
   let mut buff = String::new();
   file.read_to_string(&mut buff).unwrap();

   let foo: Foo = serde_json::from_str(&buff).unwrap();
   println!("Name: {}", foo.name);
}
Run Code Online (Sandbox Code Playgroud)


new*_*e99 6

您可以将此功能提取到实用程序中。根据他们的文档,这可能是一个有效的软件

use std::{
    fs::File,
    io::BufReader,
    path::Path,
    error::Error
};

use serde_json::Value;

fn read_payload_from_file<P: AsRef<Path>>(path: P) -> Result<Value, Box<dyn Error>> {
    // Open file in RO mode with buffer
    let file = File::open(path)?;
    let reader = BufReader::new(file);

    // Read the JSON contents of the file
    let u = serde_json::from_reader(reader)?;

    Ok(u)
}

fn main() {
  let payload: Value = 
     read_payload_from_file("./config/payload.json").unwrap();
}
Run Code Online (Sandbox Code Playgroud)


two*_*rec 5

有一个简短而完整的示例,说明如何从serde_json::de::from_readerdocs中的文件读取JSON 。

以下是以下内容的简短摘要:

  • 读取文件
  • 将其内容解析为JSON
  • 并使用所需的键提取字段

请享用:

let file = fs::File::open("text.json")
    .expect("file should open read only");
let json: serde_json::Value = serde_json::from_reader(file)
    .expect("file should be proper JSON");
let first_name = json.get("FirstName")
    .expect("file should have FirstName key");
Run Code Online (Sandbox Code Playgroud)