gpt4 book ai didi

rust - 解析/proc/cpuinfo 失败

转载 作者:行者123 更新时间:2023-11-29 08:29:14 24 4
gpt4 key购买 nike

我试图在 Linux 上解析 /proc/cpuinfo,但遇到了一些麻烦。

我想回来:

  • 型号名称
  • 核心
  • sibling

我想将它们作为一个结构返回,但我很乐意返回所有它们。

use std::{
collections::HashMap,
fmt,
fs::File,
io::{self, Read},
};

pub struct CPUInfo {
pub model_name: String,
pub cores: u16,
}

#[derive(Debug)]
pub enum Error {
UnsupportedSystem,
//ExecFailed(io::Error),
IO(io::Error),
Unknown,
}

impl fmt::Display for Error {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
use self::Error::*;
match *self {
UnsupportedSystem => write!(fmt, "System is not supported"),
//ExecFailed(ref e) => write!(fmt, "Execution failed: {}", e),
IO(ref e) => write!(fmt, "IO error: {}", e),
Unknown => write!(fmt, "An unknown error occurred"),
}
}
}

impl std::error::Error for Error {
fn description(&self) -> &str {
use self::Error::*;
match *self {
UnsupportedSystem => "unsupported system",
//ExecFailed(_) => "execution failed",
IO(_) => "io error",
Unknown => "unknown error",
}
}

fn cause(&self) -> Option<&std::error::Error> {
use self::Error::*;
match *self {
UnsupportedSystem => None,
//ExecFailed(ref e) => Some(e),
IO(ref e) => Some(e),
Unknown => None,
}
}
}

impl From<io::Error> for Error {
fn from(e: io::Error) -> Error {
Error::IO(e)
}
}

pub fn get_cpu() -> Result<CPUInfo, Error> {
if cfg!(target_os = "linux") {
let mut s = String::new();
File::open("/proc/cpuinfo")?.read_to_string(&mut s)?;
let mut cpuinfo_hashmap = HashMap::new();
for line in s.lines() {
let mut split_line = line.split_whitespace();
let label = split_line.next();
let value = split_line.next();
if value.is_some() && label.is_some() {
let label = label.unwrap().split(':').nth(0).ok_or(Error::Unknown)?;
let value = value.unwrap().to_string();
cpuinfo_hashmap.insert(label, value.to_string());
}
}

Ok(CPUInfo {
model_name: {
let m = cpuinfo_hashmap.get("model name").ok_or(Error::Unknown)?;
m.to_string()
},
cores: {
let c = cpuinfo_hashmap.get("siblings").ok_or(Error::Unknown)?;
let cores: u16 = c.parse::<u16>().unwrap();
cores
},
})
} else {
Err(Error::UnsupportedSystem)
}
}

fn main() {
let cpu = get_cpu().expect("error getting cpu");
println!("CPU: {} {}", cpu.model_name, cpu.cores)
}

( Rust Playground )

此代码失败:

thread 'main' panicked at 'error getting cpu: Unknown', libcore/result.rs:1009:5
note: Run with `RUST_BACKTRACE=1` for a backtrace.

然后 Reddit 上有人建议使用 derive_builder所以我尝试了:

pub fn cpu_info() -> Result<CPUInfo, Error> {
let file = File::open("/proc/cpuinfo")?;
let buf_reader = BufReader::new(file);
let mut builder = &mut CPUInfoBuilder::default();

for line in buf_reader.lines() {
let line = line.unwrap();
let kv: Vec<_> = line.splitn(2, ':').map(|s| s.trim()).collect();

builder = match kv.as_slice() {
["model name", v] => builder.model_name(v.to_string()),
["cpu cores", v] => builder.cores(v.parse::<u16>().ok().ok_or(Error::Unknown)?),
[_, _] => builder,
[_] => builder,
_ => unreachable!(),
}
}
Ok(builder.build().expect("failed"))
}

它也编译失败。

最佳答案

您的代码存在一些问题。我讨厌只为他们重写一个人的代码,但即使编译成功,你所拥有的一些东西也无法正常工作。下面的代码中有一些提示。

下面是构建您期望的结构的代码,打印到 HashMap 进行调试,然后打印结构中的信息以便于查看:

use std::{
fs::File,
io::{BufRead, BufReader, Error, ErrorKind},
};

use hashbrown::HashMap;

fn main() {
let cpu = get_cpu().unwrap();
println!("{}{}", cpu.model_name, cpu.cores);
}

pub struct CPUInfo {
pub model_name: String,
pub cores: u16,
}

pub fn get_cpu() -> Result<CPUInfo, Error> {
if cfg!(target_os = "linux") {
let f = File::open("/proc/cpuinfo")?;
let reader = BufReader::new(f);
let mut cpuinfo_hashmap: HashMap<String, String> = HashMap::new();

for line in reader.lines().take(20) {
let line = line.unwrap();
let mut split_line = line.split(':');
let label = split_line.next();
let value = split_line.next();
if value.is_some() && label.is_some() {
let label = label.unwrap().trim().to_string();
let value = value.unwrap().trim().to_string();
cpuinfo_hashmap.insert(label, value);
}
}

println!("{:?}", cpuinfo_hashmap);

Ok(CPUInfo {
model_name: {
let m = cpuinfo_hashmap
.get("model name")
.ok_or(Error::from(ErrorKind::InvalidData))?;
m.clone()
},
cores: {
let c = cpuinfo_hashmap
.get("siblings")
.ok_or(Error::from(ErrorKind::InvalidData))?;
let cores: u16 = c.parse::<u16>().unwrap_or(0);
cores
},
})
} else {
Err(Error::from(ErrorKind::Other))
}
}

你的代码有问题:

  1. 你没有发布你的导入,这让我很难过
  2. 您不能BufRead String,您需要直接BufRead File
  3. 您的变量在使用前需要解包
  4. 行需要解包并绑定(bind)到变量以防止借用检查错误
  5. 您首先在空格处拆分该行,然后在 ":" 字符处再次拆分,这为您提供了一个包含 20 个条目的 HashMap,看起来像 "processor ": ":"

关于rust - 解析/proc/cpuinfo 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54224706/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com