首页 > 解决方案 > 如何在 Rust 中搜索和解析任意长的 JSON 文件?

问题描述

所以我和一个朋友正在用 Rust 制作我们自己的包管理器,我们需要为它解析 JSON。我们找到了Rust Programming Tutorial #42 - Parsing JSON,它向我们展示了如何做到这一点的基础知识,但在我们的情况下,我们正在解析的文件可以小到 1 个条目,也可以大到 1000 个(或更多!)。下面是我们需要解析的 JSON 格式:

[
    {
    "Name": "libexample",
    "Version": "5.0.0",
    "Depends": "dependency1, dependency2, dependency3",
    "Maintainer": "example@example.com",
    "Author": "person@author.com",
    "Homepage": "www.homepage.com",
    "Depiction": "package.depiction.com/file.json",
    "Description": "This  package contains an example!",
    "State": "Stable",
    "Provides": "Example",
    "Replaces": "Free space on your hard drive",
    "OS": "darwin, linux",
    "Architecture": "amd64"
    },
    {
    "Name": "libexample",
    "Version": "6.0.0",
    "Depends": "dependency1, dependency2, dependency3",
    "Maintainer": "example@example.com",
    "Author": "person@author.com",
    "Homepage": "www.homepage.com",
    "Depiction": "package.depiction.com/file.json",
    "Description": "This  package contains an example!",
    "State": "Beta",
    "Provides": "Example",
    "Replaces": "Free space on your hard drive",
    "OS": "darwin, linux",
    "Architecture": "amd64"
    },
    {
    "Name": "libexample",
    "Version": "7.0.0",
    "Depends": "dependency1, dependency2, dependency3",
    "Maintainer": "example@example.com",
    "Author": "person@author.com",
    "Homepage": "www.homepage.com",
    "Depiction": "package.depiction.com/file.json",
    "Description": "This  package contains an example!",
    "State": "Alpha",
    "Provides": "Example",
    "Replaces": "Free space on your hard drive",
    "OS": "darwin, linux",
    "Architecture": "amd64"
    },
    {
    "Name": "libanotherexample",
    "Version": "3.8.2",
    "Depends": "dependency1, dependency2, dependency3",
    "Maintainer": "example@example.com",
    "Author": "person@author.com",
    "Homepage": "www.homepage.com",
    "Depiction": "package.depiction.com/file.json",
    "Description": "This  package contains an example!",
    "State": "Stable",
    "Provides": "Another example",
    "Replaces": "Free space on your hard drive",
    "OS": "darwin, linux",
    "Architecture": "amd64"
    }
]

我们的问题是我们不知道如何解析任意长的文件,也不知道如何搜索它们。例如,如果有人查找包名称,我们如何搜索整个文件以将其与其中一个名称条目匹配,然后显示该包的其余信息?

标签: jsonrust

解决方案


    extern crate rustc_serialize;
extern crate serde_json;
extern crate serde;
extern crate serde_derive;
use std::fs::File;
use std::io::Read;
use std::str;
use serde_derive::Serialize;
use serde_derive::Deserialize;
#[derive(Serialize ,Deserialize)]
struct Person{
    first_name: String,
    last_name: String,
    age: i64,
    }
    impl Person{
        fn show(&self){
            println!("First_Name:{}   Last_Name:{}   Age:{}",self.first_name,self.last_name,self.age);
        }
    }

fn main() {
    let mut file = File::open("text.json").unwrap();
    let mut data = Vec::new();
    file.read_to_end(&mut data).unwrap();
  let s = match str::from_utf8(&data) {
    Ok(v) => v,
    Err(e) => panic!("Invalid UTF-8 sequence: {}", e),
};
let values: Vec<_> = s.split("},").collect();
   let  mut i=0;
    while i<values.len(){
        let mut str1=values[i].to_string();
        if i==0{
             str1 = str1.replace("[", "");
            str1=str1+"}";
        }
        else if i==values.len()-1{
             str1 = str1.replace("]", "");
        }
        else{
            str1=str1.to_string()+"}";

        }
      let res=serde_json::from_str(&str1);
      if res.is_ok(){

         let p:Person=res.unwrap();
         p.show();
         }else{
        println!("Sorry ! we could not pass json");
     }
            i=i+1;

 } 
}




























/*fn main(){
    let mut file = File::open("text.json").unwrap();
    let  data = String::new();
    file.read_to_end(data).unwrap();
    let res=serde_json::from_str(&data);
    if res.is_ok(){
        let p:Person=res.unwrap();
        println!("{}",p.first_name);
        println!("{}",p.age);
    }
    else{
        println!("cannot pass the value");
    }

//     for i in data.iter(){
//     println!("{}",i);
// }
/*let s = match str::from_utf8(&data) {
    Ok(v) => v,
    Err(e) => panic!("Invalid UTF-8 sequence: {}", e),
};*/
//println!("result: {}", s);


/*let str1=String::from(s);*/
//println!("result: {}", str1);



//let  main_vec= str1.lines().map(|s| s.trim().split('}').map(String::from).collect::<Vec<String>>()).collect::<Vec<Vec<String>>>();

/*for item in (main_vec).iter(){
    println!("{:?}",item);
    let str24:String=item;
    let res=serde_json::from_str(str24);
    if res.is_ok(){
        let p:Person=res.unwrap();
        println!("{}",p.first_name);
        println!("{}",p.age);
    }
    else{
        println!("cannot pass the value");
    }*/

    /*let strings = s.split("},");
    println!("{}",strings);
    for x in strings {
        //println!("{}", x);
        let res=serde_json::from_str(x);
    if res.is_ok(){
        let p:Person=res.unwrap();
         println!("{}",p.first_name);
        println!("{}",p.age);
        println!("-----------------------");
    }
    else{
        println!("cannot pass the value");
    }*/
      }*/

推荐阅读