Ch 22: File文件操作
File是Rust中表示文件的类型,实现了Read和Writetrait,可以直接读写。它位于std::fs模块。
2. 打开和创建文件
Section titled “2. 打开和创建文件”2.1 Open打开已有文件
Section titled “2.1 Open打开已有文件”use std::fs::File;use std::io;
fn main() -> io::Result<()> { // 只读打开 let file = File::open("Cargo.toml")?;
println!("文件打开成功: {:?}", file);
Ok(())}2.2 create创建新文件
Section titled “2.2 create创建新文件”use std::fs::File;use std::io;
fn main() -> io::Result<()> { // 创建新文件(如果存在则截断) let mut file = File::create("output.txt")?;
file.write_all(b"Hello, world!")?;
println!("文件创建成功");
Ok(())}2.3 OpenOptions灵活打开
Section titled “2.3 OpenOptions灵活打开”use std::fs::{File, OpenOptions};use std::io;
fn main() -> io::Result<()> { // 追加模式打开 let file = OpenOptions::new() .write(true) .append(true) .open("output.txt")?;
file.write_all(b"\n追加的内容")?;
Ok(())}OpenOptions常用选项:
.read(true)- 读取.write(true)- 写入.append(true)- 追加.create(true)- 创建(不存在时).truncate(true)- 截断.create_new(true)- 仅创建新文件
3. 读取文件
Section titled “3. 读取文件”3.1 一次性读取
Section titled “3.1 一次性读取”use std::fs;use std::io;
fn main() -> io::Result<()> { let contents = fs::read("Cargo.toml")?; println!("文件大小: {} 字节", contents.len()); println!("内容: {}", String::from_utf8_lossy(&contents));
Ok(())}3.2 使用File和BufReader
Section titled “3.2 使用File和BufReader”use std::fs::File;use std::io::{BufRead, BufReader};
fn main() -> io::Result<()> { let file = File::open("Cargo.toml")?; let reader = BufReader::new(file);
for line in reader.lines() { println!("{}", line?); }
Ok(())}3.3 使用File直接读取
Section titled “3.3 使用File直接读取”use std::fs::File;use std::io::{Read, BufReader};
fn main() -> io::Result<()> { let file = File::open("Cargo.toml")?; let mut reader = BufReader::new(file);
let mut contents = String::new(); reader.read_to_string(&mut contents)?;
println!("文件内容:\n{}", contents);
Ok(())}4. 写入文件
Section titled “4. 写入文件”4.1 write_all
Section titled “4.1 write_all”use std::fs::File;use std::io;
fn main() -> io::Result<()> { let mut file = File::create("test.txt")?;
file.write_all(b"第一行\n")?; file.write_all(b"第二行\n")?; file.write_all(b"第三行\n")?;
Ok(())}4.2 使用BufWriter缓冲写入
Section titled “4.2 使用BufWriter缓冲写入”use std::fs::File;use std::io::{BufWriter, Write};
fn main() -> std::io::Result<()> { let file = File::create("buffered.txt")?; let mut writer = BufWriter::new(file);
for i in 0..100 { writeln!(writer, "行 {}", i)?; }
writer.flush()?;
println!("写入完成");
Ok(())}5. seek移动指针
Section titled “5. seek移动指针”5.1 Seek trait
Section titled “5.1 Seek trait”use std::fs::File;use std::io::{self, Read, Seek, SeekFrom};
fn main() -> io::Result<()> { let mut file = File::open("Cargo.toml")?;
// 移动到文件开头 file.seek(SeekFrom::Start(0))?;
// 读取前100字节 let mut buffer = [0u8; 100]; file.read(&mut buffer)?; println!("前100字节:\n{}", String::from_utf8_lossy(&buffer));
// 移动到最后 file.seek(SeekFrom::End(0))?; let pos = file.stream_position()?; println!("文件大小: {} 字节", pos);
Ok(())}5.2 SeekFrom位置
Section titled “5.2 SeekFrom位置”| 变体 | 说明 |
|---|---|
Start(n) | 从开头偏移n字节 |
End(n) | 从结尾偏移n字节(负数向前) |
Current(n) | 从当前位置偏移n字节 |
6. metadata获取文件信息
Section titled “6. metadata获取文件信息”use std::fs;
fn main() -> std::io::Result<()> { let metadata = fs::metadata("Cargo.toml")?;
println!("是否为文件: {}", metadata.is_file()); println!("是否为目录: {}", metadata.is_dir()); println!("文件大小: {} 字节", metadata.len()); println!("创建时间: {:?}", metadata.created()); println!("修改时间: {:?}", metadata.modified());
Ok(())}7. FileInfo结构
Section titled “7. FileInfo结构”| 方法 | 说明 |
|---|---|
len() | 文件大小(字节) |
is_file() | 是否是普通文件 |
is_dir() | 是否是目录 |
created() | 创建时间 |
modified() | 修改时间 |
accessed() | 访问时间 |
permissions() | 权限信息 |
8. 复制文件
Section titled “8. 复制文件”use std::fs;
fn main() -> std::io::Result<()> { // copy 复制文件 fs::copy("Cargo.toml", "Cargo.toml.bak")?;
println!("文件已复制");
// 清理 fs::remove_file("Cargo.toml.bak")?;
Ok(())}9. 实际示例:日志处理
Section titled “9. 实际示例:日志处理”use std::fs::{File, OpenOptions};use std::io::{BufRead, BufReader, Write, Seek, SeekFrom};
fn main() -> std::io::Result<()> { // 创建测试日志文件 let mut file = File::create("app.log")?; writeln!(file, "INFO: 服务器启动")?; writeln!(file, "ERROR: 连接失败")?; drop(file);
// 读取并处理日志 let file = OpenOptions::new().read(true).open("app.log")?; let reader = BufReader::new(file);
let mut error_count = 0; for line in reader.lines() { let line = line?; if line.contains("ERROR") { error_count += 1; eprintln!("发现错误: {}", line); } }
println!("总共 {} 个错误", error_count);
// 追加日志 let mut file = OpenOptions::new() .write(true) .append(true) .open("app.log")?;
writeln!(file, "INFO: 服务器关闭")?;
// 清理 std::fs::remove_file("app.log")?;
Ok(())}10. 注意事项
Section titled “10. 注意事项”- 文件句柄生命周期:File在drop时才关闭
- 读写模式:默认打开不能读写,需要使用OpenOptions
- 文件锁:
File本身不提供锁,需要用std::fs::OpenOptions - 换行符:不同操作系统换行符不同(
\nvs\r\n)
11. 总结
Section titled “11. 总结”今天我们学习了File文件操作:
- open - 以只读方式打开文件
- create - 创建新文件(截断已存在的)
- OpenOptions - 灵活的文件打开选项
- read/write - 实现Read/Write trait
- seek - 移动文件指针
- metadata - 获取文件信息
- copy/remove - 文件操作
File是Rust文件I/O的基础,正确使用File和BufReader/BufWriter可以获得良好的性能和功能。