Bạn cần hai miếng cốt lõi: File
và Read
.
Nếu bạn muốn đọc tất cả mọi thứ đến một String
:
use std::fs::File;
use std::io::Read;
fn main() {
let mut data = String::new();
let mut f = File::open("/etc/hosts").expect("Unable to open file");
f.read_to_string(&mut data).expect("Unable to read string");
println!("{}", data);
}
Nếu bạn muốn đọc tất cả mọi thứ như một tập hợp các byte:
use std::fs::File;
use std::io::Read;
fn main() {
let mut data = Vec::new();
let mut f = File::open("/etc/hosts").expect("Unable to open file");
f.read_to_end(&mut data).expect("Unable to read data");
println!("{}", data.len());
}
Không ai trong số các chức năng hoảng loạn trên riêng của họ, nhưng Tôi đang sử dụng expect
vì tôi không biết loại xử lý lỗi nào sẽ phù hợp nhất với ứng dụng của bạn.
Đây là nhẹ hơn tiết hơn các phiên bản giả thuyết đó sẽ phân bổ một String
hoặc Vec
cho bạn, nhưng là mạnh hơn ở chỗ bạn có thể tái sử dụng dữ liệu được phân bổ hoặc thêm vào sau một đối tượng hiện có. Viết một wrapper nhỏ mà phân bổ các đối tượng cho bạn là tầm thường, và có thể là một bổ sung ergonomic trong tương lai.
Viết tệp giống nhau, ngoại trừ tệp luôn được thực hiện dưới dạng byte. Bạn có thể chuyển đổi một String
/&str
để byte với as_bytes
:
use std::fs::File;
use std::io::Write;
fn main() {
let data = "Some data!";
let mut f = File::create("/tmp/foo").expect("Unable to create file");
f.write_all(data.as_bytes()).expect("Unable to write data");
}
tôi cảm thấy một chút của một push từ cộng đồng để sử dụng BufReader
và BufWriter
thay vì đọc trực tiếp từ một file
Một bộ đọc đệm (hoặc người viết) sử dụng bộ đệm để giảm số lượng yêu cầu IO. Ví dụ, nó hiệu quả hơn để truy cập đĩa một lần để đọc 256 byte thay vì truy cập đĩa 256 lần.
Điều đó đang được nói, tôi không tin rằng người đọc/người viết đã được đệm sẽ hữu ích khi đọc toàn bộ tệp.read_to_end
dường như sao chép dữ liệu trong các phần hơi lớn, do đó quá trình chuyển có thể đã được kết hợp tự nhiên thành các yêu cầu IO ít hơn.
Dưới đây là một ví dụ của việc sử dụng nó:
use std::fs::File;
use std::io::{Read, BufReader};
fn main() {
let mut data = String::new();
let f = File::open("/etc/hosts").expect("Unable to open file");
let mut br = BufReader::new(f);
br.read_to_string(&mut data).expect("Unable to read string");
println!("{}", data);
}
Và để viết:
use std::fs::File;
use std::io::{Write, BufWriter};
fn main() {
let data = "Some data!";
let f = File::create("/tmp/foo").expect("Unable to create file");
let mut f = BufWriter::new(f);
f.write_all(data.as_bytes()).expect("Unable to write data");
}
Một BufReader
là hữu ích hơn khi bạn muốn đọc line-by-line:
use std::fs::File;
use std::io::{BufRead, BufReader};
fn main() {
let f = File::open("/etc/hosts").expect("Unable to open file");
let f = BufReader::new(f);
for line in f.lines() {
let line = line.expect("Unable to read line");
println!("Line: {}", line);
}
}
Hàng đêm Ru st, có chức năng một dòng cho việc đọc và viết:
#![feature(fs_read_write)]
use std::fs;
fn main() {
let data = fs::read_string("/etc/hosts").expect("Unable to open file");
println!("{}", data);
}
#![feature(fs_read_write)]
use std::fs;
fn main() {
let data = fs::read("/etc/hosts").expect("Unable to open file");
println!("{}", data.len());
}
#![feature(fs_read_write)]
use std::fs;
fn main() {
let data = "Some data!";
fs::write("/tmp/foo", data).expect("Unable to write data");
}
tôi mong đợi này để trở thành lựa chọn phổ biến khi chúng được ổn định.
Bạn muốn đọc tệp như thế nào? Bạn có muốn nó theo từng dòng, như bạn đã hiển thị không? Bạn có muốn tất cả trong một chuỗi? Có nhiều cách để "đọc một tệp". – Shepmaster
Dù cách nào cũng tốt. Tôi để nó mở một cách cố ý. Nếu nó thu thập tất cả thành một chuỗi, tách nó thành một Vec sẽ là tầm thường, và ngược lại. Tại thời điểm này trong tìm kiếm của tôi cho các giải pháp, tôi sẽ được hạnh phúc để chỉ nhìn thấy thanh lịch, up-to-date Rust tập tin I/O mã hoạt động. –
Về lỗi tính trạng ('std :: io :: Read'), lưu ý rằng trong Rust bạn phải nhập các đặc điểm mà bạn mong muốn sử dụng * một cách rõ ràng *; Vì vậy, ở đây bạn đang thiếu một 'sử dụng std :: io :: Read' (mà có thể là một' sử dụng std :: io :: {Đọc, BufReader} 'để kết hợp hai sử dụng với nhau) –