Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Rust中搜索和解析任意长的JSON文件?_Json_Rust - Fatal编程技术网

如何在Rust中搜索和解析任意长的JSON文件?

如何在Rust中搜索和解析任意长的JSON文件?,json,rust,Json,Rust,所以我和一个朋友正在用Rust制作我们自己的包管理器,我们需要为它解析JSON。我们找到了,它向我们展示了如何做到这一点的基本知识,但在我们的情况下,我们正在解析的文件可以小到1个条目,也可以大到1000个(或更多!)。下面是我们需要解析的JSON格式: [ { "Name": "libexample", "Version": "5.0.0", "Depends": "dependency1, dependency2, dependency3", "Mai

所以我和一个朋友正在用Rust制作我们自己的包管理器,我们需要为它解析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"
    }
]
我们的问题是,我们不知道如何解析任意长度的文件,也不知道如何搜索它们。例如,如果有人查找包名,我们如何搜索整个文件以将其与其中一个名称条目相匹配,然后显示该包的其余信息?

extern-crater-rustc\u serialize;
    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");
    }*/
      }*/
外部板条箱serde_json; 外部板条箱; 外部板条箱serde_; 使用std::fs::File; 使用std::io::Read; 使用std::str; 使用serde_派生::序列化; 使用serde_派生::反序列化; #[派生(序列化、反序列化)] 结构人{ 名字:String, 姓氏:String, 年龄:164岁, } 默示人{ fn show(&self){ println!(“名字:{}姓氏:{}年龄:{}”,self.First-Name,self.Last-Name,self.Age); } } fn main(){ 让mut file=file::open(“text.json”).unwrap(); 让mut data=Vec::new(); file.read_to_end(&mut data).unwrap(); 让s=match str::from_utf8(&data){ Ok(v)=>v, Err(e)=>panic!(“无效的UTF-8序列:{}”,e), }; let值:Vec=s.split(“},”).collect(); 设muti=0; 当我, 呃(e)=>恐慌!(“无效的UTF-8序列:{}”,e), };*/ //普林顿!(“结果:{}”,s); /*设str1=String::from(s)*/ //普林顿!(“结果:{}”,str1); //让main_vec=str1.lines().map(|s | s.trim().split('}').map(String::from).collect::()).collect:(); /*对于(主向量).iter()中的项目{ println!(“{:?}”,项目); 设str24:String=item; 让res=serde_json::from_str(str24); 如果恢复正常(){ 让p:Person=res.unwrap(); println!(“{}”,p.first_name); println!(“{}”,p.age); } 否则{ println!(“无法传递值”); }*/ /*设strings=s.split(“},”); 普林顿!(“{}”,字符串); 对于字符串中的x{ //println!(“{}”,x); 设res=serde_json::from_str(x); 如果恢复正常(){ 让p:Person=res.unwrap(); println!(“{}”,p.first_name); println!(“{}”,p.age); println!(“--------------------------”); } 否则{ println!(“无法传递值”); }*/ }*/
这不是答案本身,而是一些想法:通常情况下,您不会直接搜索JSON文件,而是将其读入一个内部数据结构,该结构旨在使您的算法(搜索、更新、删除,可能排序?)简单快速。如果您的文件很长(可能有很多GB),那么一次将文件全部读入内存可能是一个问题,在这种情况下,您可能需要研究使用流式解析器。我认为serde_json支持流式传输,至少它的存在表明了这一点。@trentcl是的,我的意思是任意长,而且如果一次将其加载到内存中是一个问题,那么将其存储在数据库中(每次检查json时都会重建自身)并从中获取信息是一个更好的选择吗?如果是这样的话,那么我可能只需要知道如何在Rust中创建数据库。如果数据库不是一个好的选择(Rust似乎还没有出现,但我没有对它进行广泛的研究),那么我还能做什么呢?通过对文件进行迭代来获得包含所有信息的结构元组是否可行?如果没有,我还有什么其他选择呢?Rust,实际上是cargo,有一个本地数据库。当您安装了一个新的cargo并且第一次进行了
cargo build
时,它会
更新索引
,持续几秒钟。对于整个安装,而不是每个项目,此操作仅执行一次。我不是铁锈专家,但用“更简单的语言”获取基础知识可能比将其移植到铁锈上更容易。现有的数据库库是一个不错的选择。我不知道有什么东西存在或者对生锈有好处,这对这个网站来说无论如何都是离题的。至于其他选择——你有很多!您需要设计您的数据结构,以便您最想做的任务是最快的。您的数据比简单的JSON文件具有更多的结构;例如,
State
可能是一组固定键中的一个,
OS
可能包含一组固定键中的多个键,
dependens
包含与数据集其他成员的关系。您可以利用这些结构来提高性能和减少膨胀。您可能需要实现一些图遍历算法(例如,拓扑排序会告诉您安装依赖项的顺序),因此您需要考虑到这一点。您可能需要按名称搜索。由您定义需求。建筑问题是这里的主题,但这是一条很好的路线;我想说的是,你应该考虑一个设计,并解释为什么你认为它有问题,而不是让它为你做一个。请在发布答案之前阅读。