导读

Rust 语言是一种高效、可靠的通用高级语言。其高效不仅限于开发效率,它的执行效率也是令人称赞的,是一种少有的兼顾开发效率和执行效率的语言。

本章介绍 Rust 语言的 I/O 操作。

接收命令行参数

命令行程序是计算机程序最基础的存在形式,几乎所有的操作系统都支持命令行程序并将可视化程序的运行基于命令行机制。

命令行程序必须能够接收来自命令行环境的参数,这些参数往往在一条命令行的命令之后以空格符分隔。

在很多语言中(如 Java 和 C/C++)环境参数是以主函数的参数(常常是一个字符串数组)传递给程序的,但在 Rust 中主函数是个无参函数,环境参数需要开发者通过 std::env 模块取出,过程十分简单:

实例

fn main() {

let args = std::env::args();

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

}

现在直接运行程序:

Args { inner: ["D:\\rust\\greeting\\target\\debug\\greeting.exe"] }

也许你得到的结果比这个要长的多,这很正常,这个结果中 Args 结构体中有一个 inner 数组,只包含唯一的字符串,代表了当前运行的程序所在的位置。

但这个数据结构令人难以理解,没关系,我们可以简单地遍历它:

实例

fn main() {

let args = std::env::args();

for arg in args {

println!("{}", arg);

}

}

运行结果:

D:\rust\greeting\target\debug\greeting.exe

一般参数们就是用来被遍历的,不是吗。

现在我们打开许久未碰的 launch.json ,找到 "args": [],这里可以设置运行时的参数,我们将它写成 "args": ["first", "second"] ,然后保存、再次运行刚才的程序,运行结果:

D:\rust\greeting\target\debug\greeting.exe

first

second

作为一个真正的命令行程序,我们从未真正使用过它,作为语言教程不在此叙述如何用命令行运行 Rust 程序。但如果你是个训练有素的开发者,你应该可以找到可执行文件的位置,你可以尝试进入目录并使用命令行命令来测试程序接收命令行环境参数。

命令行输入

早期的章节详细讲述了如何使用命令行输出,这是由于语言学习的需要,没有输出是无法调试程序的。但从命令行获取输入的信息对于一个命令行程序来说依然是相当重要的。

在 Rust 中,std::io 模块提供了标准输入(可认为是命令行输入)的相关功能:

实例

use std::io::stdin;

fn main() {

let mut str_buf = String::new();

stdin().read_line(&mut str_buf)

.expect("Failed to read line.");

println!("Your input line is \n{}", str_buf);

}

令 VSCode 环境支持命令行输入是一个非常繁琐的事情,牵扯到跨平台的问题和不可调试的问题,所以我们直接在 VSCode 终端中运行程序。在命令行中运行:

D:\rust\greeting> cd ./target/debug

D:\rust\greeting\target\debug> ./greeting.exe

RUNOOB

Your input line is

RUNOOB

std::io::Stdio 包含 read_line 读取方法,可以读取一行字符串到缓冲区,返回值都是 Result 枚举类,用于传递读取中出现的错误,所以常用 expect 或 unwrap 函数来处理错误。

注意:目前 Rust 标准库还没有提供直接从命令行读取数字或格式化数据的方法,我们可以读取一行字符串并使用字符串识别函数处理数据。

文件读取

我们在计算机的 D:\ 目录下建立文件 text.txt,内容如下:

This is a text file.

这是一个将文本文件内容读入字符串的程序:

实例

use std::fs;

fn main() {

let text = fs::read_to_string("D:\\text.txt").unwrap();

println!("{}", text);

}

运行结果:

This is a text file.

在 Rust 中读取内存可容纳的一整个文件是一件极度简单的事情,std::fs 模块中的 read_to_string 方法可以轻松完成文本文件的读取。

但如果要读取的文件是二进制文件,我们可以用 std::fs::read 函数读取 u8 类型集合:

实例

use std::fs;

fn main() {

let content = fs::read("D:\\text.txt").unwrap();

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

}

运行结果:

[84, 104, 105, 115, 32, 105, 115, 32, 97, 32, 116, 101, 120, 116, 32, 102, 105, 108, 101, 46]

以上两种方式是一次性读取,十分适合 Web 应用的开发。但是对于一些底层程序来说,传统的按流读取的方式依然是无法被取代的,因为更多情况下文件的大小可能远超内存容量。

Rust 中的文件流读取方式:

实例

use std::io::prelude::*;

use std::fs;

fn main() {

let mut buffer = [0u8; 5];

let mut file = fs::File::open("D:\\text.txt").unwrap();

file.read(&mut buffer).unwrap();

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

file.read(&mut buffer).unwrap();

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

}

运行结果:

[84, 104, 105, 115, 32]

[105, 115, 32, 97, 32]

std::fs 模块中的 File 类是描述文件的类,可以用于打开文件,再打开文件之后,我们可以使用 File 的 read 方法按流读取文件的下面一些字节到缓冲区(缓冲区是一个 u8 数组),读取的字节数等于缓冲区的长度。

注意:VSCode 目前还不具备自动添加标准库引用的功能,所以有时出现"函数或方法不存在"一样的错误有可能是标准库引用的问题。我们可以查看标准库的注释文档(鼠标放到上面会出现)来手动添加标准库。

std::fs::File 的 open 方法是"只读"打开文件,并且没有配套的 close 方法,因为 Rust 编译器可以在文件不再被使用时自动关闭文件。

文件写入

文件写入分为一次性写入和流式写入。流式写入需要打开文件,打开方式有"新建"(create)和"追加"(append)两种。

一次性写入:

实例

use std::fs;

fn main() {

fs::write("D:\\text.txt", "FROM RUST PROGRAM")

.unwrap();

}

这和一次性读取一样简单方便。执行程序之后, D:\text.txt 文件的内容将会被重写为 FROM RUST PROGRAM 。所以,一次性写入请谨慎使用!因为它会直接删除文件内容(无论文件多么大)。如果文件不存在就会创建文件。

如果想使用流的方式写入文件内容,可以使用 std::fs::File 的 create 方法:

实例

use std::io::prelude::*;

use std::fs::File;

fn main() {

let mut file = File::create("D:\\text.txt").unwrap();

file.write(b"FROM RUST PROGRAM").unwrap();

}

这段程序与上一个程序等价。

注意:打开的文件一定存放在可变的变量中才能使用 File 的方法!

File 类中不存在 append 静态方法,但是我们可以使用 OpenOptions 来实现用特定方法打开文件:

实例

use std::io::prelude::*;

use std::fs::OpenOptions;

fn main() -> std::io::Result {

let mut file = OpenOptions::new()

.append(true).open("D:\\text.txt")?;

file.write(b" APPEND WORD")?;

Ok(())

}

运行之后,D:\text.txt 文件内容将变成:

FROM RUST PROGRAM APPEND WORD

OpenOptions 是一个灵活的打开文件的方法,它可以设置打开权限,除append 权限以外还有 read 权限和 write 权限,如果我们想以读写权限打开一个文件可以这样写:

实例

use std::io::prelude::*;

use std::fs::OpenOptions;

fn main() -> std::io::Result {

let mut file = OpenOptions::new()

.read(true).write(true).open("D:\\text.txt")?;

file.write(b"COVER")?;

Ok(())

}

运行之后,D:\text.txt 文件内容将变成:

COVERRUST PROGRAM APPEND WORD

linux底层文件io,学习Rust 文件与 IO相关推荐

  1. linux java运行class文件_jvm学习java文件运行过程

    汇编 汇编的目的是把汇编语言转为机器语言. 链接 链接是要解决目标文件之间的互相依赖关系,当a文件中的aa方法中调用了b文件的bb方法时,在汇编完成后,a文件的bb方法并没有准确的内存地址,链接后会转 ...

  2. Linux学习笔记——文件IO

    文章目录 前言 C语言操作文件的函数 系统接口 文件描述符 文件系统 动态库和静态库 前言   在系统角度理解文件:文件=内容+属性,内容和属性都是数据,对于文件的所有操作无外乎对于文件内容操作和对于 ...

  3. 【嵌入式Linux】嵌入式Linux应用开发基础知识之文件IO

    文章目录 前言 1.文件从哪来 2.文件如何访问 2.1.通用IO模型open/read/write/lseek/close 2.1.1.通用IO模型使用示例 2.1.2.open/read/writ ...

  4. linux之文件基本操作学习笔记

    前言 通过本教程你将熟悉linux文件的基本操作以及其具体使用.本文目录结构摘抄自<鸟哥的LINUX私房菜>基础学习篇(第三版). 备注: 本文只摘录了部分书中内容,对于部分知识点不会做详 ...

  5. Linux目录结构,命令,文件类型学习

    2019独角兽企业重金招聘Python工程师标准>>> [toc] Linux目录结构,命令,文件类型学习 一. 系统目录结构 简述 对于目录,我们大致能够理解,像书本学的章节,每个 ...

  6. 嵌入式Linux自学笔记(二)——文件IO

    一.简介 本节讨论Unix系统中大多数文件用到的5个函数:open,read,write,lseek,close.本节描述的函数经常被称为不带缓冲的IO.不带缓冲指的是每个read和write都调用内 ...

  7. LinuxC—标准IO与文件IO学习笔记

    标准IO与文件IO 1 概述 stdio 标准IO(优先使用) sysio 系统调用IO(文件IO) sysio是直接实现用户态切换内核态,sysio和平台是有关系的,比如windows和linux, ...

  8. 《Linux操作系统 - 高级编程》第一部分 标准IO及文件IO(第2章 标准IO)

    2.1 Linux I/O概述 2.1.1文件I/O和标准I/O的概念 文件I/O:文件I/O称之为不带缓存的IO(unbuffered I/O).不带缓存指的是每个read,write都调用内核中的 ...

  9. linux文件怎么操作,linux文件操作学习1

    由于实验室的项目需要开始学习linux,为了更好的学习和掌握linux的一些基本操作以及顺便做个备忘录,时间久了也可以看看自己的学习成果. 学习linux应该先抛开windows的C.D.E...盘的 ...

最新文章

  1. 产品开发的 11 宗罪
  2. AI已经融入生活,不懂AI的人已经out了,五分钟了解AI人工智能!
  3. webform开发经验(一):Asp.Net获取Checkbox选中的值
  4. mysql cpu 内存占用_MySQL占用内存与CPU过高测试与解决办法
  5. 虚拟主机上传SQLServer数据库--不完全资料
  6. HDU - 3410 Passing the Message 单调递减栈
  7. [补档]noip2019集训测试赛(八)
  8. 系列文章--SharePoint 2013 开发教程
  9. getSelectionStart() doesn't work in android, is always 0
  10. scratch编程小游戏——黄金矿工
  11. php网页 背景图片,HTML怎么设置网页背景图
  12. luogu P5064 [Ynoi2014] 等这场战争结束之后
  13. BGP和BGP机房各为什么?优势在哪?
  14. idea创建三种应用程序的方法:springboot,控制台程序,windows服务程序
  15. 一款消消乐游戏的自动解法
  16. word合并邮件无法发送html,Word邮件合并批量发送带附件的邮件
  17. 软考复习笔记|项目管理过程与可行性分析及可行性分析报告编写
  18. 5G,建设得怎么样了?
  19. 阿里云接口手机归属地查询API
  20. Python库之Scipy库的简介、安装详细

热门文章

  1. MVC中 数据底层联合JQUERY实现动态的安全的验证机制
  2. 可视化与办公自动化学习
  3. 转:验证curl_init() 返回 false时..
  4. 番茄瑜伽13招-学好可以疏经活血祛风止痛
  5. 每天一个Linux命令-cat
  6. 阿里rocketmq与自建rocketmq
  7. wubiuefi-支持新版本ubuntu的wubi
  8. 使用mybatis插入数据(insert)时返回主键的问题
  9. Spring Swagger URL传参问题(转)
  10. BDD(行为驱动开发)