在前两篇文章中我们已经学习和了解了Rust编程语言的大概知识点以及常见的应用场景以及Web的开发和数据库的连接。
接下来,本篇文章博主通过Rust系统编程语言,进行当前系统内存、CPU等信息获取,以及简单实现图片采集并设置系统壁纸功能。

系统信息

博主这里主要是想体验下Rust在获取系统基本信息的功能如何,我们直接上代码直接体验。

使用sysinfo库

首先在 Cargo.toml 中添加依赖:

[dependencies]
sysinfo = "0.29"
cargo run

sysinfo库报错提示

这个错误是因为 sysinfo 库的 API 发生了变化。查阅资料后发现,在新版本中,global_cpu_usage() 方法已经被移除。
在这里插入图片描述
这个错误是因为需要导入 ProcessExt trait 来使用 memory() 方法。
在这里插入图片描述
完成上面处报错代码修改后,下面是完整可运行的代码。
在使用过程中,难免会碰到一些未知的问题,但是这些都不是问题,大部分都能找到解决方法。

系统信息代码

完成代码如下:

use sysinfo::{System, SystemExt, CpuExt, DiskExt, NetworkExt, ProcessExt};
fn main() {
let mut sys = System::new_all();
// 刷新所有信息
sys.refresh_all();
// 内存信息
println!("=== 内存信息 ===");
println!("总内存: {} MB", sys.total_memory() / 1024 / 1024);
println!("已用内存: {} MB", sys.used_memory() / 1024 / 1024);
println!("可用内存: {} MB", sys.available_memory() / 1024 / 1024);
println!("总交换空间: {} MB", sys.total_swap() / 1024 / 1024);
println!("已用交换空间: {} MB", sys.used_swap() / 1024 / 1024);
// CPU信息
println!("\n=== CPU信息 ===");
println!("CPU数量: {}", sys.cpus().len());
// 计算全局CPU使用率的方法
let global_cpu_usage = if !sys.cpus().is_empty() {
sys.cpus().iter().map(|cpu| cpu.cpu_usage()).sum::<f32>() / sys.cpus().len() as f32
  } else {
  0.0
  };
  println!("全局CPU使用率: {:.1}%", global_cpu_usage);
  // 显示每个CPU核心的使用率
  for (i, cpu) in sys.cpus().iter().enumerate() {
  println!("CPU {}: {:.1}%", i, cpu.cpu_usage());
  }
  // 系统信息
  println!("\n=== 系统信息 ===");
  println!("系统名称: {:?}", sys.name());
  println!("内核版本: {:?}", sys.kernel_version());
  println!("OS版本: {:?}", sys.os_version());
  println!("主机名: {:?}", sys.host_name());
  // 磁盘信息
  println!("\n=== 磁盘信息 ===");
  for disk in sys.disks() {
  println!(
  "磁盘: {:?} 总大小: {} GB 可用: {} GB",
  disk.name(),
  disk.total_space() / 1024 / 1024 / 1024,
  disk.available_space() / 1024 / 1024 / 1024
  );
  }
  // 网络信息
  println!("\n=== 网络信息 ===");
  for (interface_name, data) in sys.networks() {
  println!(
  "{}: 接收 {} MB, 发送 {} MB",
  interface_name,
  data.received() / 1024 / 1024,
  data.transmitted() / 1024 / 1024
  );
  }
  // 进程信息 - 修正部分
  println!("\n=== 进程信息 ===");
  println!("进程数量: {}", sys.processes().len());
  // 显示前5个内存使用最多的进程
  let mut processes: Vec<_> = sys.processes().values().collect();
    processes.sort_by(|a, b| b.memory().cmp(&a.memory()));
    for process in processes.iter().take(5) {
    println!(
    "PID: {} 名称: {:?} 内存: {} MB",
    process.pid(),
    process.name(),
    process.memory() / 1024 / 1024
    );
    }
    }

系统信息运行效果

在这里插入图片描述
在这里插入图片描述

从上图很清晰的展示博主真实的笔记本电脑信息,博主这台笔记本电脑已经使用3年多的时间,i5、16GB内存,512GB固态,整体配置不算太高。

主要库对比

在这里插入图片描述
推荐使用 sysinfo 库,因为它功能全面、文档完善,并且在所有主要平台上都能良好工作。

实时监控程序

通过上面可以获取到系统基本信息后,那么就可以做一个简单的实时监控,查看系统整体运行情况的程序,
是不是有点熟悉的感觉,没错,类似一个任务管理器一样。

实时监控常见报错

这个错误是因为 refresh_cpu_usage() 方法在新版本中已被移除。正确的做法是使用 refresh_cpu()。
在这里插入图片描述
这个错误是因为 uptime() 是实例方法,不是静态方法。需要从系统实例调用。
在这里插入图片描述

实时监控代码

完成代码如下:

use std::{thread, time::Duration};
use sysinfo::{System, SystemExt, CpuExt, ProcessExt};
fn monitor_system() {
let mut sys = System::new_all();
loop {
// 刷新系统信息
sys.refresh_cpu();
thread::sleep(Duration::from_secs(1));
sys.refresh_memory();
sys.refresh_processes();
// 清屏并显示信息
println!("\x1B[2J\x1B[1;1H"); // 清屏
println!("=== 系统实时监控 ===");
println!("更新时间: {:?}", sys.uptime()); // 修正:使用 sys.uptime()
// 内存信息
println!("\n=== 内存信息 ===");
println!("总内存: {:>6} MB", sys.total_memory() / 1024 / 1024);
println!("已用内存: {:>6} MB", sys.used_memory() / 1024 / 1024);
println!("可用内存: {:>6} MB", sys.available_memory() / 1024 / 1024);
println!("使用率: {:>6.1}%",
(sys.used_memory() as f64 / sys.total_memory() as f64) * 100.0);
// CPU信息
println!("\n=== CPU信息 ===");
let global_cpu_usage = if !sys.cpus().is_empty() {
sys.cpus().iter().map(|cpu| cpu.cpu_usage()).sum::<f32>() / sys.cpus().len() as f32
  } else {
  0.0
  };
  println!("CPU核心数: {}", sys.cpus().len());
  println!("全局使用率: {:.1}%", global_cpu_usage);
  // 显示每个CPU核心的使用率柱状图
  for (i, cpu) in sys.cpus().iter().enumerate() {
  let usage = cpu.cpu_usage();
  let bars = (usage / 5.0) as usize;
  let bar = "=".repeat(bars.min(20));
  let spaces = " ".repeat(20 - bars.min(20));
  println!("CPU {:2}: [{}{}] {:5.1}%", i, bar, spaces, usage);
  }
  // 进程信息
  println!("\n=== 内存占用前5的进程 ===");
  let mut processes: Vec<_> = sys.processes().values().collect();
    processes.sort_by(|a, b| b.memory().cmp(&a.memory()));
    println!("{:<6} {:<20} {:<10}", "PID", "进程名", "内存(MB)");
    println!("{}", "-".repeat(40));
    for process in processes.iter().take(5) {
    println!("{:<6} {:<20} {:<10}",
    process.pid(),
    process.name(),
    process.memory() / 1024 / 1024
    );
    }
    // 系统信息
    println!("\n=== 系统信息 ===");
    println!("系统运行时间: {} 秒", sys.uptime()); // 修正:使用 sys.uptime()
    println!("进程总数: {}", sys.processes().len());
    println!("\n按 Ctrl+C 退出监控...");
    // 等待2秒后刷新
    thread::sleep(Duration::from_secs(2));
    }
    }
    fn main() {
    println!("启动系统监控...");
    println!("按 Ctrl+C 可以退出程序");
    thread::sleep(Duration::from_secs(2));
    // 启动实时监控
    monitor_system();
    }

实时监控运行效果

在这里插入图片描述

壁纸操作

添加依赖

actix-web = "4.4"  # 如果还没有的话
reqwest = { version = "0.11", features = ["blocking", "json"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
chrono = { version = "0.4", features = ["serde"] }
image = "0.24"
wallpaper = "3"
dirs = "4.0"

下面的错误表示wallpaper当前的版本不存在,并且还给出了建议,这个我觉得非常的友好。
在这里插入图片描述
设置好正确的版本后,保存,然后cargo run运行后会自动下载依赖。
在这里插入图片描述

完整代码

use std::fs::File;
use std::io::copy;
use std::path::PathBuf;
use dirs::picture_dir;
fn main() -> Result<(), Box<dyn std::error::Error>> {
  println!("开始获取必应每日壁纸...");
  // 1. 获取必应图片URL
  let image_url = get_bing_image_url()?;
  println!("获取到图片URL: {}", image_url);
  // 2. 下载图片
  let image_path = download_image(&image_url)?;
  println!("图片已下载到: {:?}", image_path);
  // 3. 设置为壁纸
  set_wallpaper(&image_path)?;
  println!("壁纸设置成功!");
  Ok(())
  }
  fn get_bing_image_url() -> Result<String, Box<dyn std::error::Error>> {
    // 必应每日图片API
    let api_url = "https://cn.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1&mkt=zh-CN";
    let response = reqwest::blocking::get(api_url)?;
    let json: serde_json::Value = response.json()?;
    // 解析JSON获取图片URL
    if let Some(images) = json["images"].as_array() {
    if let Some(first_image) = images.get(0) {
    if let Some(url) = first_image["url"].as_str() {
    let full_url = format!("https://cn.bing.com{}", url);
    return Ok(full_url);
    }
    }
    }
    Err("无法解析必应图片URL".into())
    }
    fn download_image(url: &str) -> Result<PathBuf, Box<dyn std::error::Error>> {
      // 创建响应
      let response = reqwest::blocking::get(url)?;
      // 获取文件扩展名
      let extension = if url.contains(".jpg") || url.contains(".jpeg") {
      "jpg"
      } else if url.contains(".png") {
      "png"
      } else {
      "jpg" // 默认
      };
      // 生成文件名
      let file_name = format!("bing_wallpaper_{}.{}",
      chrono::Local::now().format("%Y%m%d_%H%M%S"),
      extension
      );
      // 保存到图片目录
      let mut picture_dir = picture_dir().ok_or("无法获取图片目录")?;
      picture_dir.push("bing_wallpapers");
      // 创建目录(如果不存在)
      std::fs::create_dir_all(&picture_dir)?;
      let file_path = picture_dir.join(file_name);
      // 下载并保存文件
      let mut dest = File::create(&file_path)?;
      let mut content = std::io::Cursor::new(response.bytes()?);
      copy(&mut content, &mut dest)?;
      Ok(file_path)
      }
      fn set_wallpaper(image_path: &PathBuf) -> Result<(), Box<dyn std::error::Error>> {
        // 使用 wallpaper 库设置壁纸
        wallpaper::set_from_path(image_path.to_str().ok_or("无效的图片路径")?)?;
        // 设置壁纸模式(居中、平铺、拉伸等)
        wallpaper::set_mode(wallpaper::Mode::Crop)?;
        Ok(())
        }

壁纸下载效果

在这里插入图片描述
上图已经提示已经下载到本地,并且设置好了壁纸,到对应文件夹目录即可看到下载好的壁纸图片,如下:
在这里插入图片描述

壁纸设置效果

在这里插入图片描述

总结

博主在使用过程中,发现有些版本和当前使用的方法不一致,这点可能大家在使用过程中需要特别注意,整体上来说,想要的方法和解决方案都能快速找到,也不会花费太多时间,只要养成了解的编程习惯和思维,很多开发语言都是相通的,所以,博主在0到1学习再到实战会相对上手快一些,也能快速理解其中的含义。

文章推荐

【Rust】系统编程语言的核心语法以及常见应用场景浅谈:系统、Web、网络、命令行
【Rust】从0到1开发和运行Web相关功能,并简单实现数据库连接和查询
【Rust】通过系统编程语言获取当前系统内存、CPU等运行情况,以及简单实现图片采集并设置系统壁纸