fs và io: Truyền tệp và byte
Mô tả thời gian tồn tại của tệp, trạng thái đọc toàn bộ, chuyển một phần và sau lỗi.
Wave Foundation
Chọn tệp API
Chức năng tiện lợi của std::fs::file nhận đường dẫn và thực hiện việc mở và đóng cần thiết. Các hàm trả về một bộ mô tả phải được người gọi đóng lại.
| khai báo | Kết quả thành công và biện pháp phòng ngừa |
|---|---|
open_read(path: str) -> i64 |
Mở mô tả. Số âm là lỗi |
create(path: str) -> i64 |
Tạo hoặc xóa nội dung tập tin hiện có. Trả về bộ mô tả sở hữu |
open_append(path: str) -> i64 |
Mở hoặc tạo để bổ sung |
size(path: str) -> i64 |
Số byte. Số âm là lỗi |
read_into(path: str, dst: ptr<u8>, dst_cap: i64) -> i64 |
Số byte trong toàn bộ tập tin. Thiếu năng lực là một lỗi |
read_to_end(path: str, dst_buffer: ptr<Buffer>) -> i64 |
Thêm tệp sau Buffer hiện có và trả lại số tiền bổ sung |
write(path: str, src: ptr<u8>, len: i64) -> i64 |
Số byte được ghi thay thế nội dung hiện có |
append(path: str, src: ptr<u8>, len: i64) -> i64 |
Số byte được thêm vào cuối |
remove(path: str) -> i64 |
tình trạng loại bỏ. thất bại là tiêu cực |
Riêng false của exists(path) không thể phân biệt được giữa thiếu file và lỗi cấp phép. Hãy chắc chắn kiểm tra kết quả mở thực tế vì trạng thái có thể thay đổi giữa việc kiểm tra sự tồn tại và mở.
Mức độ thấp I/O
std::io::fd
io_read(fd: i64, buf: ptr<u8>, len: i64) -> i64
io_write(fd: i64, buf: ptr<u8>, len: i64) -> i64
io_read_exact(fd: i64, buf: ptr<u8>, len: i64) -> i64
io_write_all(fd: i64, buf: ptr<u8>, len: i64) -> i64
io_close(fd: i64) -> i64
Kết quả dương tính của io_read là số byte được đọc và 0 trong yêu cầu có độ dài dương là EOF. io_write có thể được viết ít hơn yêu cầu. Nếu cần chuyển toàn bộ, hãy sử dụng chức năng exact/all. Tuy nhiên, chúng tôi không cho rằng lỗi sẽ hoàn nguyên trạng thái bên ngoài vì một số lần chuyển có thể đã xảy ra trước khi xảy ra lỗi.
io_read_exact là lỗi nếu gặp EOF trước độ dài yêu cầu. read_into trả về IO_ERR_NO_SPACE nếu bộ đệm đầy và một số byte có thể đã được ghi. Chức năng đọc không tự động thêm NUL vào cuối chuỗi.
Buffer và xử lý lỗi
Nếu không thành công, read_to_end khôi phục len gốc nhưng dung lượng và địa chỉ dữ liệu của nó có thể đã thay đổi. Người gọi phải giải phóng Buffer sau khi thành công hoặc thất bại. API ghi tệp không đảm bảo thay thế tệp nguyên tử.
Từ Luyện đọc file, bạn có thể chạy chương trình từ import để phát hành. Hãy xem xét sự khác biệt về đường dẫn/quyền trong Linux/macOS/Windows/FreeBSD và các hạn chế về thư mục có thể truy cập trong WASI. Nó không diễn giải trực tiếp giá trị mô tả dưới dạng mã điều khiển thô của một OS khác.
Đọc các tệp lớn vào bộ đệm nhỏ
Các thao tác không yêu cầu đặt toàn bộ tệp vào bộ nhớ có thể được xử lý bằng bộ đệm cố định và đọc lặp lại. Chương trình sau in nội dung của input.txt và đếm tổng số byte đã đọc. Lưu một Wave và LF trong tệp đầu vào.
import("std::fs::file")::{open_read};
import("std::io::fd")::{io_read, io_write_all, io_close};
import("std::io::consts")::{IO_STDOUT_FD};
fun main() -> i32 {
var descriptor: i64 = open_read("input.txt");
if (descriptor < 0) {
return 1;
}
var buffer: array<u8, 4>;
var total: i64 = 0;
while (true) {
var count: i64 = io_read(descriptor, &buffer[0], 4);
if (count < 0) {
io_close(descriptor);
return 2;
}
if (count == 0) {
break;
}
if (io_write_all(IO_STDOUT_FD, &buffer[0], count) < 0) {
io_close(descriptor);
return 3;
}
total += count;
}
if (io_close(descriptor) < 0) {
return 4;
}
println("bytes={}", total);
return 0;
}
Kết quả thực hiện:
Wave
bytes=5
Dung lượng bộ đệm là 4, nhưng lần đọc cuối cùng có thể là 1 byte. Chúng tôi luôn chuyển count thực tế vào đầu ra. Nếu bạn ghi toàn bộ mảng, thậm chí cả các byte cũ, chưa đọc cũng có thể được xuất ra.
Chương trình đã mở descriptor trong số input.txt, vì vậy hãy đóng nó lại. Đầu ra tiêu chuẩn không phải là tài nguyên mới có được trong hàm này, vì vậy nó không bị đóng tùy ý ở cuối ví dụ.
Đọc đầy đủ và không đủ năng lực
read_into nhận được một không gian lưu trữ cố định chứa toàn bộ tệp. Nếu không đủ dung lượng, nó sẽ âm thầm cắt bớt và trả về NO_SPACE nhưng không thành công.
import("std::fs::file")::{read_into};
import("std::io::consts")::{IO_ERR_NO_SPACE};
fun main() {
var data: array<u8, 2>;
var status: i64 = read_into("input.txt", &data[0], 2);
if (status == IO_ERR_NO_SPACE) {
println("destination too small");
}
}
Kết quả thực hiện:
destination too small
Nó không cho rằng việc đọc thất bại hoàn toàn không thay đổi byte đích. Không sử dụng nó làm nội dung tệp hoàn chỉnh, hãy chuẩn bị một kho lưu trữ lớn hơn hoặc chọn phương thức streaming. Ngay cả khi bạn truy vấn kích thước trước, kết quả đọc thực tế vẫn là phán quyết cuối cùng vì tệp có thể thay đổi giữa truy vấn và đọc.
Sự khác biệt giữa ghi và nối thêm tập tin
write thay thế nội dung hiện có và append được thêm vào cuối. Số byte cần lưu trữ có thể được lấy trực tiếp từ độ dài chuỗi và được truyền. NUL ở cuối chuỗi thường không có trong nội dung tệp văn bản.
import("std::fs::file")::{write, append, size, remove};
import("std::string::len")::{len};
fun main() -> i32 {
var first: str = "Wave";
var second: str = " study";
if (write("output.txt", first as ptr<u8>, len(first) as i64) < 0) {
return 1;
}
if (append("output.txt", second as ptr<u8>, len(second) as i64) < 0) {
return 2;
}
println("bytes={}", size("output.txt"));
if (remove("output.txt") < 0) {
return 3;
}
return 0;
}
Kết quả thực hiện:
bytes=10
Ví dụ này tạo, thay thế và cuối cùng xóa output.txt trong thư mục làm việc. Chạy từ thư mục thực hành không có tập tin hiện có. Trình chỉnh sửa hoặc chương trình lưu trữ thực tế có thể yêu cầu các chính sách lưu trữ riêng biệt, chẳng hạn như các tệp tạm thời và thay thế.
API Bảng tuyển chọn
| tình huống | chọn |
|---|---|
| Đọc toàn bộ tệp nhỏ vào bộ đệm cố định | read_into |
| Giữ toàn bộ nội dung mà không cần biết kích thước | read_to_end và Buffer |
| Xử lý nội dung theo thứ tự thay vì lưu trữ toàn bộ nội dung | open_read + io_read lặp lại |
| Đọc bản ghi có độ dài cố định | io_read_exact |
| Truyền toàn bộ chuỗi byte | io_write_all |
| Xử lý các tập tin đã mở | Hàm fd thay vì hàm đường dẫn |
Sau khi chọn một chức năng, hãy kiểm tra xem bộ đệm, vị trí tệp và dữ liệu bên ngoài thay đổi như thế nào trong trường hợp xảy ra lỗi.