赞
踩
在类unix系统中,一切都是文件,所以说广义的文件操作,其实包括很多:Socket、管道、内存映射等等。其实文件操作无论怎么变化,主流仍然是对外设的访问。计算机本身的组成,是一系列的硬件整合在一起的,单纯的只有CPU和内存是搞不动事情的。所以,一谈到文件操作,一定要清晰的看穿是哪类文件操作。
文件操作,其实就是对IO操作的一种的抽象。这种抽象隔离开了不同设备的不同之处,由具体的设备驱动来解决这种抽象的不同。所以,读写文件的API,有read,write,也有send和recv,其实就是演进的一个过程。这篇文章只是分析对存储文件,也就是说常见的数据存储文件的操作的分析,是一种狭义的文件操作的文章。
一般来说,计算机语言对文件的操作都有比较好的更上层的抽象接口。但是C/C++有点例外,他们基本上是使用了原始的API,搞得操作文件各种异常的问题都需要自己处理。如果有人写过用C处理读取一个大文件就明白这句话的意思。而Java、go等语言处理起文件的操作来,就相对要省心许多。c++标准库过了这么多年,包括c++11迭代到c++17才有一部分对文件操作的API。但是作为后起的Rust,这方面的顾虑就要少很多,对文件的操作的支持要相对好很多。
在文件操作中,一般来说,可以按字符串来操作也可以按流来操作。既可以一次性读写,也可以按指定条件读写。文件的操作一般是四个过程:
1、创建
//路径创建
create_dir<P: AsRef
create_dir_all<P: AsRef
//文件创建
create<P: AsRef
std::fs::remove_file<P: AsRef
2、打开
open<P: AsRef
3、读或者写
read(&mut self, buf: &mut [u8]) -> Result
read_to_string(&mut self, buf: &mut String) -> Result
seek(&mut self, pos: SeekFrom) -> Result
take(self, limit: u64) -> Take
fn write(&mut self, buf: &[u8]) -> Result :将缓冲区数据写入文件,有可能失败。
fn flush(&mut self) -> Result<()>
fn write_all(&mut self, buf: &[u8]) -> Result<()> : 连续调用 write,将 缓冲区数据写入文件。
4、关闭:Rust会自动处理
也就是说,在c/c++中相关的文件操作和其它语言中的相关的动作,都可以在Rust中找到相关的接口。
下面先看一个创建文件例子:
use std::fs; fn main() -> std::io::Result<()> { // 创建空目录 fs::create_dir("./mydir")?; // 创建级联目录 fs::create_dir_all("./mydir/test")?; // 创建路径 let path = Path::new("./mypath/a.txt"); // 返回路径 let parent = path.parent().unwrap(); // 得到文件名,无扩展名 let fname = path.file_stem().unwrap(); Ok(()) }
再看一个读文件的:
use std::fs::File; use std::io; use std::io::prelude::*; fn main() -> io::Result<()> { let mut f = File::open("a.txt")?; let mut buf = [0; 12]; // 读取文件12 byte let n = f.read(&mut buf[..])?; // read 12 let n = f.read(&mut buf[..])?; let mut f = File::open("a.txt")?; let mut buf = String::new(); f.read_to_string(&mut buf)?; Ok(()) }
再看一个写文件的:
use std::fs::File;
use std::io::prelude::*;
fn main() -> std::io::Result<()> {
let mut buf = File::create("a.txt")?;
buf.write(b"example---")?;
buf.write_all(b"all txt write test!")?;
buf.flush()?;
Ok(())
}
如果想实现类似C/C++中API的读写方式可以使用fs::OpenOptions:
use std::io::prelude::*;
use std::fs::OpenOptions;
fn main() -> std::io::Result<()> {
let mut f = OpenOptions::new()
.append(true).open("e:\\mytxt.txt")?;
f.write(b" append data")?;
Ok(())
}
Rust中还有一些操作文件的小细节,这里就不再一一赘述。
其实,很多的细节可以决定一个语言的成败。例如c++这种语言如果现在才推出来(指的是最初版本的),估计基本上没人用。但很多事情都是时也运也。在那个时代,没有这么大把的语言出现,也没有这么多上层的应用出现,更多的还是一种接近于研究向普及转化的过程的时代。c++承上启下,其实有很大的现实意义的。
作为Rust,看到了c++的情况,应该认真的吸取经验教训,站好自己的位置,管好自己的一亩三分地的同时,该出手时还是要出手的。
努力吧,归来的少年!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。