json - 如何在 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"
}
]
我们的问题是我们不知道如何解析任意长的文件,也不知道如何搜索它们。例如,如果有人查找包名称,我们如何搜索整个文件以将其与其中一个名称条目匹配,然后显示该包的其余信息?
解决方案
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");
}*/
}*/
推荐阅读
- python-3.x - 如何在 Windows 10 上运行 pyautogui 脚本时使用计算机?
- swift - 自定义中缀运算符和选项
- java - 创建 2 个线程,每个线程运行不同的任务
- postgresql - AWS EC2 Postgres 身份验证失败
- android - 使用 Glide 4.11 “尝试使用回收的位图”时崩溃,转换会导致这种情况吗?
- java - 如何获得“减少”以将流中的值彼此分开?
- tensorflow - “LayerNormLSTMCell”对象在 tf 2.2 中没有属性“zero_state”
- c++ - 在这种情况下如何存储数组的总和
- javascript - React 中未定义的属性“映射”
- c# - .NET 前端中的 SQL 存储过程验证(类似于 SSMS 中的解析选项)