[Rust Serial] Bài 5: Thao tác với Texting processing, File and Directory trong Rust
Outline
- Chương 0: Thao tác với File
- Chương 1: Thao tác với thư mục
- Chương 2: Text Processing
- Chương 3: Một số thư viện
References:
Chương 0: Thao tác với File
Các kiểu thao tác vói file
- Mở một file
- Tạo mới một file
- Đóng một file
- Ghi tới file
- Đọc metadata từ file
- Đọc dữ liệu từ file
Eg 1:
Eg 2: Tạo một file mới và ghi
Chú ý hàm write
cần mảng các bytes &[u8]
Mở một file
let f = File::open("hello.txt").expect("Could not open file");
Cách khác sử dụng OpenOptions
fn open_with_open_options() {
let file = OpenOptions::new()
.read(true)
.write(true)
.create(true)
.open("foo.txt")
.unwrap();
}
- Mở với quyền đọc, ghi, ghi thêm
pub fn read(&mut self, read: bool) -> &mut Self
pub fn write(&mut self, write: bool) -> &mut Self
pub fn append(&mut self, append: bool) -> &mut Self
pub fn truncate(&mut self, truncate: bool) -> &mut Self
pub fn create(&mut self, create: bool) -> &mut Self
pub fn create_new(&mut self, create_new: bool) -> &mut Self
Khác nhau của create
và create_new
là create_new
sẽ lỗi nếu file đã tồn tại
Tạo một file mới
fn create_file() {
let mut f = File::create("hello2.txt").expect("Could not create file");
}
Đóng một file
fn write_file() {
let mut f = File::create("hello2.txt").expect("Could not create file");
f.write("buffer".as_bytes())
.expect("Could not write to file");
f.close();
}
Ghi tới file
fn write_file() {
let mut f = File::create("hello2.txt").expect("Could not create file");
f.write("buffer".as_bytes())
.expect("Could not write to file");
}
Đọc metadata của file
- File type
- is dir or not?
- symbol link ?
- len
- permission
- modified time
- access time
- created time
fn main() -> std::io::Result<()> {
use std::fs;
let metadata = fs::metadata("foo.txt")?;
println!("{:?}", metadata.file_type());
assert!(!metadata.is_dir());
Ok(())
}
refer: https://doc.rust-lang.org/std/fs/struct.Metadata.html
Đọc dữ liệu từ file
- Đọc theo từng single byte
- Đọc vào buffer
- Đọc theo từng chunk bytes
- Đọc theo từng dòng
- Đọc đến cuối
- Đọc từ cuối (Di chuyển con trỏ để đọc)
Đọc theo từng single byte
fn read_with_single_bytes() {
let mut file = OpenOptions::new()
.read(true)
.write(true)
.create(true)
.open("hello.txt")
.unwrap();
for i in file.bytes() {
println!("Byte: {:?}", i.unwrap());
}
}
Đọc vào buffer
fn read_with_single_bytes() {
let mut file = OpenOptions::new()
.read(true)
.write(true)
.create(true)
.open("hello.txt")
.unwrap();
let mut buffer = [0; 10];
file.read(&mut buffer).unwrap();
println!("Buffer contents: {:?}", buffer);
}
Đọc theo từng chunk bytes
fn read_with_buffer() {
let mut file = OpenOptions::new()
.read(true)
.write(true)
.create(true)
.open("hello.txt")
.unwrap();
let mut buffer = [0; 10];
file.read(&mut buffer).unwrap();
println!("Buffer contents: {:?}", buffer);
}
Đọc đến cuối
Nó nhận đầu vào là 1 vector
fn read_to_end() {
let mut file = OpenOptions::new()
.read(true)
.write(true)
.create(true)
.open("hello.txt")
.unwrap();
let mut buffer = vec![0; 1000];
file.read_to_end(&mut buffer).unwrap();
println!("Buffer contents: {:?}", buffer);
}
Đọc từ cuối (Di chuyển con trỏ để đọc)
fn read_with_reader4_from_end() {
let file = OpenOptions::new()
.read(true)
.write(true)
.create(true)
.open("hello.txt")
.unwrap();
const CAP: usize = 1024 * 128; // 128 KB
let mut reader = BufReader::with_capacity(CAP, file);
// let mut reader = BufReader::new(file);
let r = reader.seek(std::io::SeekFrom::End(0));
let mut buf = String::new();
reader.seek_relative(-10);
reader.read_to_string(&mut buf);
println!("Line: {:?}", buf);
}
Đọc sử dụng BufReader
fill_buf
: Trở về nội dung của buffer bên trong, fill it với nhiều dữ liệu nhấtconsume
: Nói rằng buffer đã tiêu thụ n bytes và không được trở về từ hàmread
nữa.read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> Result<usize>
: Đọc đến ký tựbyte
thì dừng lạiskip_until
: Bỏ qua đến khi gặp ký tựread_lin
đọc đến khi gặp0xA
thì dừngrewind
: Quay lại đầu file, streamseek
: Di chuyển con trỏ đọc đến vị trí
pub enum SeekFrom {
Start(u64),
End(i64),
Current(i64),
}
Homework 1.1: Read the n th last line of a file
Homework 1.2: Figure out about std::path::Path
Chương 1: Thao tác với thư mục
https://rust-lang-nursery.github.io/rust-cookbook/file/dir.html
List các danh sách files từ một folder
- Cách 1:
Hàm
fs::read_dir
fn dir_read_paths() {
let paths = fs::read_dir("./").unwrap();
for path in paths {
println!("Name: {}", path.unwrap().path().display())
}
}
- Cách 2:
use glob::glob;
fn main() {
for e in glob("../*").expect("Failed to read glob pattern") {
println!("{}", e.unwrap().display());
}
}
- Cách 3:
use walkdir::WalkDir;
fn main() {
for e in WalkDir::new(".").into_iter().filter_map(|e| e.ok()) {
if e.metadata().unwrap().is_file() {
println!("{}", e.path().display());
}
}
}
List recusely files
fn recurse(path: impl AsRef<Path>) -> Vec<PathBuf> {
let Ok(entries) = read_dir(path) else { return vec![] };
entries.flatten().flat_map(|entry| {
let Ok(meta) = entry.metadata() else { return vec![] };
if meta.is_dir() { return recurse(entry.path()); }
if meta.is_file() { return vec![entry.path()]; }
vec![]
}).collect()
}
Homework 2: Read the n th last line of a file
Chương 2: Text Processing
Homework 3: Read the n th last line of a file
Regex
Json file
Thanks for reading! Read other posts?