【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);
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/web/82209.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微服务中引入公共拦截器

本文使用的微服务版本为springcloudAlbaba :2021.0.4.0 微服务工程&#xff0c;一般公共的东西都放入一个工程&#xff0c;别的微服务都会引入这个工程&#xff0c;比如common-service,那么就可以在这个工程编写一个拦截器&#xff1a;&#xff0c;比如&#xff1a; public cla…

Linux SLES 系统的/var/log/下的常见文件及其作用

在 SUSE Linux Enterprise Server&#xff08;SLES&#xff09; 系统中&#xff0c;/var/log/ 目录是系统日志的集中地&#xff0c;存储了各种服务、内核、系统消息的日志。以下是一些在 /var/log/ 下常见的日志文件及其功能&#xff1a; &#x1f4c2; 常见日志文件及功能 文…

oracle goldengate同步SQL server到SQL server的实时数据同步

参考文档 https://docs.oracle.com/en/middleware/goldengate/core/19.1/oggmp/oracle-goldengate-classic-sql-server.html#GUID-948C5BEE-E7A0-4CE2-BE09-F83145677D18 https://docs.oracle.com/en/middleware/goldengate/core/21.3/ggcab/other-programs-and-settings-sql-…

语音转文字工具

平时工作和学习比较忙&#xff0c;可能没时间听讲座&#xff0c;只能看回放&#xff0c;回访也很长&#xff0c;这时&#xff0c;我们可以借助语言转文字&#xff0c;通过阅读文字快速了解讲座的重点&#xff0c;今天给大家分享一个本人经常用的语言转文字工具&#xff0c;改工…

硬件实时时钟(RTC)

硬件实时时钟&#xff08;RTC&#xff09;详解 硬件实时时钟&#xff08;Real-Time Clock&#xff0c;RTC&#xff09;是计算机主板上的一个独立计时芯片&#xff0c;用于在系统关机后持续记录时间。它不依赖操作系统&#xff0c;由纽扣电池&#xff08;如CR2032&#xff09;供…

pycharm debug的时候无法debug到指定的位置就停住不动了

报错大致是这样的&#xff0c;但是直接run没有问题&#xff0c;debug就停住不动了 Traceback (most recent call last): File "/home/mapengsen/.pycharm_helpers/pydev/_pydevd_bundle/pydevd_comm.py", line 467, in start_client s.connect((host, port)) Timeou…

Python6.1打卡(day33)

DAY 33 MLP神经网络的训练 知识点回顾&#xff1a; 1.PyTorch和cuda的安装 2.查看显卡信息的命令行命令&#xff08;cmd中使用&#xff09; 3.cuda的检查 4.简单神经网络的流程 1.数据预处理&#xff08;归一化、转换成张量&#xff09; 2.模型的定义 …

NodeJS全栈开发面试题讲解——P11消息队列(MQ)

✅ 11.1 为什么要用消息队列&#xff1f;在哪些场景下最适合&#xff1f; ✅ 作用&#xff1a; 削峰填谷&#xff1a;缓解高并发压力&#xff0c;异步处理任务&#xff08;如秒杀下单 → MQ → 异步扣库存&#xff09; 解耦服务&#xff1a;上下游解耦&#xff08;如下单服务…

mysql执行sql语句报错事务锁住

报错情况 1205 - Lock wait timeout exceeded; try restarting transaction先找出长时间运行的事务 SELECT * FROM information_schema.INNODB_TRX ORDER BY trx_started ASC;终止长时间运行的事务 KILL [PROCESS_ID];

C#集合循环删除某些行

你想要在遍历集合&#xff08;例如List&#xff09;的同时删除某些元素时&#xff0c;直接在循环中删除元素可能会导致问题&#xff0c;因为这可能会改变集合的大小和导致索引问题&#xff1b; 可以用for循环的倒序来删除&#xff1b; 如果要删除满足特定条件的所有元素&…

裂缝仪在线监测装置:工程安全领域的“实时守卫者”

在基础设施运维领域&#xff0c;裂缝扩展是威胁建筑结构安全的核心隐患之一。传统人工巡检方式存在效率低、时效性差、数据主观性强等局限&#xff0c;而裂缝仪在线监测装置通过技术迭代&#xff0c;实现了对结构裂缝的自动化、持续性追踪&#xff0c;为工程安全评估提供科学依…

Multisim14使用教程详尽版--(2025最新版)

一、Multisim14前言 1.1、主流电路仿真软件 1. Multisim:NI开发的SPICE标准仿真工具,支持模拟/数字电路混合仿真,内置丰富的元件库和虚拟仪器(示波器、频谱仪等),适合教学和竞赛设计。官网:艾默生旗下测试和测量系统 - NI。 2. LTspice XVII:ADI旗下免费高性能SPICE仿…

深度学习篇---人脸识别中的face-recognition库和深度学习

深度学习方法和使用 Python 的face_recognition库进行人脸识别在技术原理、实现方式和应用场景上有显著区别&#xff0c;以下从多个维度对比分析&#xff1a; 一、技术原理 1. 深度学习方法 核心逻辑&#xff1a;基于神经网络&#xff08;如卷积神经网络 CNN&#xff09;构建…

Go语言中的数据类型转换

Go 语言中只有强制类型转换&#xff0c;没有隐式类型转换。 1. 数值类型之间的相互转换 1.1. 整型和整型之间的转换 package main import "fmt"func main() {var a int8 20var b int16 40fmt.Println(int16(a) b)// 60 }1.2. 浮点型和浮点型之间的转换 packag…

行为型:中介者模式

目录 1、核心思想 2、实现方式 2.1 模式结构 2.2 实现案例 3、优缺点分析 4、适用场景 5、注意事项 1、核心思想 目的&#xff1a;通过引入一个中介对象来封装一组对象之间的交互&#xff0c;解决对象间过度耦合、频繁交互的问题。不管是对象引用维护还是消息的转发&am…

node_modules\node-sass: Command failed.报错了

node_modules\node-sass: Command failed.错误解决 第一步&#xff1a;删掉:目录中划红线的配置文件 删掉项目中的node_modules第二步&#xff1a;用admin权限执行&#xff0c;重新配置npm和yarn npm config set registry https://registry.npm.taobao.org --global npm con…

STM32 ADC工作原理与配置详解

文章目录 ADCADC简介逐次逼近型ADCADC框图ADC框图的工作流程&#xff08;以规则组为例&#xff09;1. 输入通道选择与信号接入2. 触发转换&#xff1a;软件或硬件触发3. 采样保持与量化编码4. 转换结果处理与存储5. 状态标志与中断6. 参考电压与时钟驱动7. 辅助功能&#xff1a…

1、Pytorch介绍与安装

1、Pytorch介绍 PyTorch 是由 Facebook AI Research (FAIR) 团队开发并维护的一款开源深度学习框架&#xff0c;于 2016 年首次发布。它因其直观的设计、卓越的灵活性以及强大的动态计算图功能&#xff0c;迅速在学术界和工业界获得了广泛认可&#xff0c;成为当前深度学习研究…

RedisTemplate查询不到redis中的数据问题(序列化)

RedisTemplate查询不到redis中的数据问题(序列化) 一.问题描述 存入Redis中的值取出来却为null,问题根本原因就是RedisTemplate和StringRedisTemplate的序列化问题、代码示例&#xff1a; SpringBootTest class Redis02SpringbootApplicationTests {Autowiredprivate RedisTe…

【Net】TCP粘包与半包

文章目录 TCP粘包与半包1 背景2 粘包&#xff08;packet stick&#xff09;3 半包&#xff08;packet split&#xff09;4 为什么会出现粘包/半包&#xff1f;5 如何解决&#xff1f;6 示例7 总结 TCP粘包与半包 在网络编程中&#xff0c;粘包和半包问题是常见的 TCP 协议特有…