当前位置: 首页 > article >正文

【Rust】Rust获取命令行参数以及IO操作

在这里插入图片描述

✨✨ 欢迎大家来到景天科技苑✨✨

🎈🎈 养成好习惯,先赞后看哦~🎈🎈

🏆 作者简介:景天科技苑
🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。
🏆《博客》:Rust开发,Python全栈,Golang开发,云原生开发,PyQt5和Tkinter桌面开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi,flask等框架,云原生K8S,linux,shell脚本等实操经验,网站搭建,数据库等分享。

所属的专栏:Rust语言通关之路
景天的主页:景天科技苑

在这里插入图片描述

文章目录

  • Rust获取命令行参数以及IO操作
    • 1、接收命令行参数
      • 1.1 读取参数值
      • 1.2 将参数值保存进变量
    • 2、Rust读取文件
      • 2.1. 基本文件读取
        • 2.1.1 一次性读取整个文件到字符串
        • 2.1.2 一次性读取整个文件到字节向量
      • 2.2. 逐行读取文件
        • 2.2.1 使用 BufReader 逐行读取
        • 2.2.2 使用 BufReader 读取字节块
      • 2.3 使用内存映射文件 (memmap2)
    • 3、Rust向文件中写内容
    • 4、Rust序列化与反序列化

Rust获取命令行参数以及IO操作

Rust作为一门系统编程语言,提供了强大且安全的I/O操作支持。与C/C++不同,Rust通过所有权系统和丰富的类型系统,在编译期就能避免许多常见的I/O错误。Rust的标准库std::io模块包含了大多数I/O功能,而std::fs模块则专门处理文件系统操作。

1、接收命令行参数

1.1 读取参数值

Rust 标准库提供的std::env::args 能够获取传递给它的命令行参数的值
这个函数返回一个传递给程序的命令行参数的 迭代器(iterator)。

use std::env;fn main() {let args: Vec<String> = env::args().collect();println!("{:?}", args);
}

首先使用 use 语句来将 std::env 模块引入作用域以便可以使用它的 args 函数。
注意 std::env::args 函数被嵌套进了两层模块中。
当所需函数嵌套了多于一层模块时,通常将父模块引入作用域,而不是其自身。
这便于我们利用 std::env 中的其他函数。这比增加了 use std::env::args; 后仅仅使用 args 调用函数要更明确一些,因为 args 容易被错认成一个定义于当前模块的函数。

得到的第一个参数是生成的程序本身,后面都是命令行参数
在这里插入图片描述

在 main 函数的第一行,我们调用了 env::args,并立即使用 collect 来创建了一个包含迭代器所有值的 vector。
collect 可以被用来创建很多类型的集合,所以这里显式注明 args 的类型来指定我们需要一个字符串 vector。
虽然在 Rust 中我们很少会需要注明类型,然而 collect 是一个经常需要注明类型的函数,因为 Rust 不能推断出你想要什么类型的集合。
最后,我们使用调试格式 :? 打印出 vector。

注意 vector 的第一个值是 “target\debug\myargs.exe”,它是我们二进制文件的名称。这与 C 中的参数列表的行为相匹配,让程序使用在执行时调用它们的名称。
如果要在消息中打印它或者根据用于调用程序的命令行别名更改程序的行为,通常可以方便地访问程序名称,不过考虑到本章的目的,我们将忽略它并只保存所需的两个参数。

注意args 函数和无效的 Unicode
注意 std::env::args 在其任何参数包含无效 Unicode 字符时会 panic。
如果你需要接受包含无效 Unicode 字符的参数,使用 std::env::args_os 代替。这在某些操作系统中可能发生
这个函数返回 OsString 值而不是 String 值。
OsString 值每个平台都不一样而且比 String 值处理起来更为复杂。

use std::env;fn main() {for arg in env::args_os() {println!("{:?}", arg);}
}

在这里插入图片描述

1.2 将参数值保存进变量

打印出参数 vector 中的值展示了程序可以访问指定为命令行参数的值。现在需要将这两个参数的值保存进变量这样就可以在程序的余下部分使用这些值了。

use std::env;fn main() {//获取命令行参数let args: Vec<String> = env::args().collect();//获取查询字符串和文件名let query = &args[1];let filename = &args[2];println!("Searching for {}", query);println!("In file {}", filename);
}

正如之前打印出 vector 时所看到的,程序的名称占据了 vector 的第一个值 args[0],所以我们从索引 1 开始。
myargs2 获取的第一个参数是需要搜索的字符串,所以将其将第一个参数的引用存放在变量 query 中。第二个参数将是文件名,所以将第二个参数的引用放入变量 filename 中。
在这里插入图片描述

2、Rust读取文件

在 Rust 中读取文件是常见的 I/O 操作,标准库提供了多种方法来处理文件读取。下面我将详细介绍各种文件读取方法及其适用场景

2.1. 基本文件读取

2.1.1 一次性读取整个文件到字符串
use std::fs;use std::io;//读取文件内容
fn read_file(filename: &str) -> io::Result<String> {// 使用?来处理错误// ?会将错误传递给调用者// ?只能在返回Result的函数中使用// ?会将错误类型从io::Error转换为io::Result<String>//fs::read_to_string返回Result<String, io::Error>let content = fs::read_to_string(filename)?;Ok(content)
}fn main() {let filename = "hello.txt";match read_file(filename) {Ok(content) => println!("File content: {}", content),Err(e) => println!("Error: {}", e),}
}

在这里插入图片描述

2.1.2 一次性读取整个文件到字节向量

用于读取二进制文件

//读取文件到字节向量
use std::fs;
use std::io;//读取二进制文件内容
fn read_file(filename: &str) -> io::Result<Vec<u8>> {// 使用?来处理错误// ?会将错误传递给调用者// ?只能在返回Result的函数中使用// ?会将错误类型从io::Error转换为io::Result<Vec<u8>>//fs::read返回Result<Vec<u8>, io::Error>let content = fs::read(filename)?;Ok(content)
}fn main() {let filename = "123.vip";match read_file(filename) {//打印文件的字节长度Ok(content) => println!("File clength: {}", content.len()),Err(e) => println!("Error: {}", e),}
}

在这里插入图片描述

2.2. 逐行读取文件

对于大文件,逐行读取更高效且内存友好。

2.2.1 使用 BufReader 逐行读取
//读取大文件
use std::fs::File;
use std::io::{ BufRead, BufReader };//读取大文件内容
fn read_file(filename: &str) -> std::io::Result<()> {let file = File::open(filename)?;let reader = BufReader::new(file);for line in reader.lines() {println!("{}", line?);}Ok(())
}fn main() {let filename = "hello.txt";match read_file(filename) {Ok(()) => println!("File content: {}", filename),Err(e) => println!("Error: {}", e),}
}

在这里插入图片描述

特点:
内存效率高
自动处理换行符
lines() 返回 Result<String>,需要处理可能的错误

2.2.2 使用 BufReader 读取字节块
//使用 BufReader 读取字节块
use std::io::{ self, Read };
use std::fs::File;//读取字节块
fn read_file(filename: &str) -> io::Result<()> {let file = File::open(filename)?;let mut reader = io::BufReader::new(file);//定义一个字节缓冲区//缓冲区的大小为1024字节let mut buffer = [0; 10];//循环读取字节块//read方法会将字节块读取到缓冲区中//read方法返回读取的字节数//如果读取到文件末尾,就退出循环loop {let n = reader.read(&mut buffer)?;if n == 0 {break; //读取到文件末尾,退出循环}println!("Read {} bytes: {:?}", n, &buffer[..n]);// 处理 buffer[..n]}Ok(())
}fn main() {match read_file("Cargo.toml") {Ok(()) => println!("Read file successfully"),Err(e) => println!("Error: {}", e),}
}

在这里插入图片描述

特点:
适用于二进制文件
可以控制缓冲区大小
适合网络传输或处理大文件

2.3 使用内存映射文件 (memmap2)

对于超大文件,内存映射可以提高性能:

use std::fs::File;
use memmap2::Mmap;fn main() -> std::io::Result<()> {let file = File::open("Cargo.toml")?;//使用memmap2映射文件到内存,需要使用unsafe,需要注意let mmap = unsafe { Mmap::map(&file)? };// 假设我们搜索某个字节模式let pattern = b"\xDE\xAD\xBE\xEF";if let Some(pos) = mmap.windows(pattern.len()).position(|w| w == pattern) {println!("Pattern found at offset: {}", pos);} else {println!("Pattern not found");}Ok(())
}

注意:内存映射涉及 unsafe 代码,需要谨慎使用。

3、Rust向文件中写内容

//写入文件
use std::fs;
use std::io;fn write_file(filename: &str, content: &str) -> io::Result<()> {fs::write(filename, content)
}fn main() {let filename = "hello.txt";let content = "你好,景天";match write_file(filename, content) {Ok(()) => println!("Write file successfully"),Err(e) => println!("Error: {}", e),}
}

在这里插入图片描述

4、Rust序列化与反序列化

使用 serde 库可以方便地进行 I/O 操作:
需要安装第三方库
cargo add serde
cargo add serde_json
并且在Cargo.toml中配置
在这里插入图片描述

//序列化和反序列化
use serde::{ Serialize, Deserialize };
use std::fs;
use serde_json;#[derive(Serialize, Deserialize, Debug)]
#[allow(dead_code)]
struct Person {name: String,age: u8,phones: Vec<String>,
}fn main() {let person = Person {name: "John".to_string(),age: 30,phones: vec!["1234567890".to_string(), "0987654321".to_string()],};//序列化let json = serde_json::to_string(&person).unwrap(); //将结构体序列化为json字符串println!("json: {}", json);//将序列化后的数据写入文件fs::write("person.json", json).unwrap(); //将数据写入文件,json的所有权已经移动到write中了//反序列化// let person2: Person = serde_json::from_str(&json).unwrap(); //这里json所有权已不存在// println!("person2: {:?}", person2);//从文件中读取数据并反序列化let json2 = fs::read_to_string("person.json").unwrap();let person3: Person = serde_json::from_str(&json2).unwrap();println!("person3: {:?}", person3);
}

在这里插入图片描述

相关文章:

【Rust】Rust获取命令行参数以及IO操作

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…...

【Redis】Zset 有序集合

文章目录 常用命令zaddzcardzcountzrange && zrevrangezrangebyscorezpopmax && bzpopmaxzpopmin && zpopmaxzrank && zrevrankzscorezremzremrangebyrankzremrangebyscorezincrby 集合间操作交集 zinterstore并集 zunionstore 内部编码应用场…...

manus对比ChatGPT-Deep reaserch进行研究类论文数据分析!谁更胜一筹?

目录 没有账号&#xff0c;只能挑选一个案例 1、manus的效果 Step-1&#xff1a;直接看结果 Step-2&#xff1a;看看其他文件的细节 Step-3&#xff1a;看最终报告 2、Deep reaserch 3、Deep reaserch进行行业分析 总结一下&#xff1a; 大家好这里是学术Anan&#xff…...

【 HarmonyOS 5 入门系列 】鸿蒙HarmonyOS示例项目讲解

【 HarmonyOS 5 入门系列 】鸿蒙HarmonyOS示例项目讲解 一、前言&#xff1a;移动开发声明式 UI 框架的技术变革 在移动操作系统的发展历程中&#xff0c;UI 开发模式经历了从命令式到声明式的重大变革。 根据华为开发者联盟 2024 年数据报告显示&#xff0c;HarmonyOS 设备…...

AWS Transit Gateway实战:构建DMZ隔离架构,实现可控的网络互通

在企业云网络架构中,如何实现不同VPC之间的安全互通是一个常见挑战。本文将通过AWS Transit Gateway实战,展示如何构建一个DMZ隔离架构,使DMZ可以与Test和Production环境互通,而Test和Production环境之间相互隔离。 1. Transit Gateway架构设计概述 在开始实践前,让我们先…...

用提示词写程序(3),VSCODE+Claude3.5+deepseek开发edge扩展插件V2

edge扩展插件;筛选书签,跳转搜索,设置背景 链接: https://pan.baidu.com/s/1nfnwQXCkePRnRh5ltFyfag?pwd86se 提取码: 86se 导入解压的扩展文件夹: 导入扩展成功: edge扩展插件;筛选书签,跳转搜索,设置背景...

栈与队列:数据结构的有序律动

在数据结构的舞台上&#xff0c;栈与队列宛如两位优雅的舞者&#xff0c;以独特的节奏演绎着数据的进出规则。它们虽不像顺序表与链表那般复杂多变&#xff0c;却有着令人着迷的简洁与实用&#xff0c;在众多程序场景中发挥着不可或缺的作用。今天&#xff0c;就让我们一同去探…...

初识PS(Photoshop)

初识PS&#xff08;Photoshop&#xff09; 1、Photoshop界面 2、常用快捷键...

go语言的GMP(基础)

1.概念梳理 1.1线程 通常语义中的线程&#xff0c;指的是内核级线程&#xff0c;核心点如下&#xff1a; &#xff08;1&#xff09;是操作系统最小调度单元&#xff1b; &#xff08;2&#xff09;创建、销毁、调度交由内核完成&#xff0c;cpu 需完成用户态与内核态间的切…...

电路图识图基础知识-高、低压供配电系统电气系统的继电自动装置(十三)

电气系统的继电自动装置 在供电系统中为保证系统的可靠性&#xff0c;保证重要负荷的不间断供电&#xff0c;常采用自动重合闸装置和备用电源自动投入装置。 1 自动重合闸装置 供配电系统多年运行实践表明&#xff0c;架空线路发生的故障多属于暂时性故障&#xff0c;如雷击…...

JDK21深度解密 Day 9:响应式编程模型重构

【JDK21深度解密 Day 9】响应式编程模型重构 引言&#xff1a;从Reactor到虚拟线程的范式转变 在JDK21中&#xff0c;虚拟线程的引入彻底改变了传统的异步编程模型。作为"JDK21深度解密"系列的第91天&#xff0c;我们将聚焦于响应式编程模型重构这一关键主题。通过…...

在 Linux 服务器上无需 sudo 权限解压/打包 .7z 的方法(实用命令)

7z的压缩比很高&#xff0c;可以把100G的文件压到3-5G&#xff0c;在大文件传输上很有优势但是一般服务器上是只有tar解压&#xff0c;用户没法&#xff08;没有权限&#xff09;直接安装7z工具来解压因此使用conda安装p7zip库可以很好地解决这个问题~ 关于7z的相关背景知识&am…...

微信小程序(uniapp)实现腾讯云 IM 消息撤回

uniapp 实现腾讯云 IM 消息撤回功能实战指南 一、功能实现原理 腾讯云 IM 的消息撤回功能通过 消息修订&#xff08;Message Revision&#xff09; 机制实现&#xff0c;核心流程如下&#xff1a; 发送方调用撤回 API 删除指定消息云端生成撤回通知消息&#xff08;类型为 T…...

设计学生管理系统的数据库

在设计学生管理系统的数据库时&#xff0c;需要考虑多个实体及其关系。以下是一个基本的学生管理系统表结构设计&#xff0c;涵盖了核心实体和关系&#xff1a; 1. 用户表 (user) 存储所有系统用户的基本信息&#xff0c;包括学生、教师和管理员。 sql CREATE TABLE user (u…...

ArcGIS Pro 3.4 二次开发 - 图形图层

环境:ArcGIS Pro SDK 3.4 + .NET 8 文章目录 图形图层1.1 创建图形图层1.2 访问GraphicsLayer1.3 复制图形元素1.4 移除图形元素2 创建图形元素2.1 使用CIMGraphic创建点图形元素2.2 使用CIMGraphic创建线图元素2.3 使用 CIMGraphic 的多边形图形元素2.4 使用CIMGraphic创建多…...

Linux配置DockerHub镜像源配置

个人博客地址&#xff1a;Linux配置DockerHub镜像源配置 | 一张假钞的真实世界 因为某些原因&#xff0c;DockerHub官方镜像源已不可用&#xff0c;国内一些镜像源也已不可用&#xff0c;大家可以搜索可用的镜像源并修改配置。推荐一篇良心博文&#xff1a;https://zhuanlan.z…...

JDK21深度解密 Day 11:云原生环境中的JDK21应用

【JDK21深度解密 Day 111】云原生环境中的JDK21应用 本文是《JDK21深度解密:从新特性到生产实践的全栈指南》专栏的第11天内容,聚焦云原生环境中的JDK21应用。我们将深入探讨如何在容器化、微服务、Serverless等云原生架构中充分发挥JDK21的技术优势,提升Java应用的性能、稳…...

如何学习才能更好地理解人工智能工程技术专业和其他信息技术专业的关联性?

要深入理解人工智能工程技术专业与其他信息技术专业的关联性&#xff0c;需要跳出单一专业的学习框架&#xff0c;通过 “理论筑基 - 实践串联 - 跨学科整合” 的路径构建系统性认知。以下是分阶段、可落地的学习方法&#xff1a; 一、建立 “专业关联” 的理论认知框架 绘制知…...

Qt实现的水波进度条和温度进度条

一.效果 二.原理 1.水波 要模拟波浪,就要首先画出一条波浪线,正弦余弦曲线就很适合。 y=A*sin(ω*x+φ)+k y=A*cos(ω*x+φ)+k 这是正弦余弦曲线的公式,要想实现水波效果,那需要两条曲线,一条曲线的波峰对着另外一条曲线的波谷,要实现这样的曲线效果,只有让正弦曲线前移…...

3516cv610在sample_aiisp上多创一路编码流,方法

3516cv610在sample_aiisp上多创一路编码流&#xff0c;方法 首先确保 vpss grp0有视频流 最好保证 已经有一路视频流能推出来 多创一路编码流思路为 将 vpss grp0又绑定给 vpss_chn1 vpss_chn1有绑定给 venc_chn1 这样我们就多创了一路视频流。 这里思路完全正确 可以实现…...

WEBSTORM前端 —— 第3章:移动 Web —— 第4节:移动适配-VM

目录 一、适配方案 二、VM布局 ​编辑 三、vh布局 四、案例—酷我音乐 一、适配方案 二、VM布局 三、vh布局 四、案例—酷我音乐...

Android第十一次面试补充篇

Livedata内存泄漏解决​ 1. 未正确绑定 LifecycleOwner​ ​原因​&#xff1a; 使用 observe() 时未传入正确的 LifecycleOwner&#xff08;如 Activity/Fragment&#xff09;&#xff0c;或误用 Application 等长生命周期对象&#xff0c;导致观察者无法自动解除绑定。 ​…...

【Zephyr 系列 3】多线程与调度机制:让你的 MCU 同时干多件事

好的,下面是Zephyr 系列第 3 篇:聚焦 多线程与调度机制的实践应用,继续面向你这样的 Ubuntu + 真板实战开发者,代码清晰、讲解通俗、结构规范,符合 CSDN 高质量博客标准。 🧠关键词:Zephyr、线程调度、k_thread、k_sleep、RTOS、BluePill 📌适合人群:想从裸机开发进…...

Kotlin-特殊类型

文章目录 数据类型枚举类型匿名类和伴生对象单例类伴生对象 数据类型 声明一个数据类非常简单: //在class前面添加data关键字表示为一个数据类 data class Student(var name: String, var age: Int)数据类声明后,编译器会根据主构造函数中声明的所有属性自动为其生成以下函数…...

nssctf第二题[SWPUCTF 2021 新生赛]简简单单的逻辑

这是题目&#xff0c;下载后得到一个python文件,打开 解读代码&#xff1a; for i in range(len(list)):key (list[i]>>4)((list[i] & 0xf)<<4)result str(hex(ord(flag[i])^key))[2:].zfill(2)list[i]>>4&#xff1a;从列表中取数字同时高4位向右位…...

《Discuz! X3.5开发从入门到生态共建》第3章 Discuz! X3.5 核心目录结构解析-优雅草卓伊凡

《Discuz! X3.5开发从入门到生态共建》第3章 Discuz! X3.5 核心目录结构解析-优雅草卓伊凡 3.1 系统核心目录结构 Discuz! X3.5采用模块化设计&#xff0c;主要目录结构如下&#xff1a; discuz_root/ ├─ api/ // API接口目录 ├─ config/ …...

【HarmonyOS 5】鸿蒙应用实现发票扫描、文档扫描输出PDF图片或者表格的功能

【HarmonyOS 5】鸿蒙应用实现发票扫描、文档扫描输出PDF图片或者表格的功能 一、前言 图(1-1) HarmonyOS 系统提供的核心场景化视觉服务,旨在帮助开发者快速实现移动端文档数字化功能。 其核心能力包括:扫描合同、票据、会议记录并保存为 PDF 分享。拍摄课堂 PPT、书籍章…...

Python_day43

DAY 43 复习日 作业&#xff1a; kaggle找到一个图像数据集&#xff0c;用cnn网络进行训练并且用grad-cam做可视化 进阶&#xff1a;并拆分成多个文件 关于 Dataset 从谷歌图片中抓取了 1000 多张猫和狗的图片。问题陈述是构建一个模型&#xff0c;该模型可以尽可能准确地在图像…...

STM32CubeDAC及DMA配置

STM32CubeDAC及DMA配置 一&#xff0c;问题1二&#xff0c;解决11&#xff0c;宏观思路CubeMX配置2&#xff0c;HAL_TIM_Base_Start(&htim6) 的作用1&#xff0c;作用1&#xff1a;使能TIM6的时钟并让它开始计数2&#xff0c;作用2&#xff1a;当 TIM6 溢出时&#xff0c;会…...

SQL快速入门【转自牛客网】

来源:牛客网 1、SQL 基础查询 在 SQL 中,SELECT 语句是最基本的查询语句,用于从数据库表中检索数据。通过 SELECT 语句,可以选择表中的所有列或特定列,并根据需要进行过滤和排序。 基本语法 SELECT 语句的基本语法如下: SELECT column1, column2, ... FROM table_na…...