Rust 1.x에서 파일을 읽고 쓰는 사실상의 방법은 무엇입니까?
Rust가 비교적 새롭기 때문에 파일을 읽고 쓰는 방법이 너무 많습니다. 많은 사람들이 블로그를 위해 만든 매우 지저분한 스 니펫이며, 내가 찾은 예제의 99 % (Stack Overflow에서도)는 더 이상 작동하지 않는 불안정한 빌드에서 나왔습니다. 이제 Rust가 안정 되었으니 파일을 읽거나 쓰기위한 간단하고 읽기 쉽고 당황하지 않는 스 니펫은 무엇입니까?
이것은 내가 텍스트 파일을 읽는 측면에서 작동하는 것에 가장 가깝지만 내가 가져야 할 모든 것을 포함했다고 확신하더라도 여전히 컴파일되지 않습니다. 이것은 모든 장소의 Google+에서 찾은 스 니펫을 기반으로하며 내가 변경 한 유일한 것은 이전 BufferedReader
이 이제 다음과 같다는 것입니다 BufReader
.
use std::fs::File;
use std::io::BufReader;
use std::path::Path;
fn main() {
let path = Path::new("./textfile");
let mut file = BufReader::new(File::open(&path));
for line in file.lines() {
println!("{}", line);
}
}
컴파일러는 다음과 같이 불평합니다.
error: the trait bound `std::result::Result<std::fs::File, std::io::Error>: std::io::Read` is not satisfied [--explain E0277]
--> src/main.rs:7:20
|>
7 |> let mut file = BufReader::new(File::open(&path));
|> ^^^^^^^^^^^^^^
note: required by `std::io::BufReader::new`
error: no method named `lines` found for type `std::io::BufReader<std::result::Result<std::fs::File, std::io::Error>>` in the current scope
--> src/main.rs:8:22
|>
8 |> for line in file.lines() {
|> ^^^^^
요약하자면 제가 찾고있는 것은 다음과 같습니다.
- 짧음
- 가독성
- 가능한 모든 오류를 다룹니다.
- 당황하지 않는다
여기에 표시 한 기능 중 어느 것도 자체적으로 당황 expect
하지 않지만 어떤 종류의 오류 처리가 귀하의 응용 프로그램에 가장 적합할지 모르기 때문에 사용 하고 있습니다. 자신의 프로그램에서 오류를 적절하게 처리하는 방법을 이해하려면 The Rust Programming Language 의 오류 처리 장을 읽어보십시오 .
Rust 1.26 이상
기본 세부 사항에 관심이없는 경우 읽기 및 쓰기를위한 한 줄 함수가 있습니다.
파일 읽기 String
use std::fs;
fn main() {
let data = fs::read_to_string("/etc/hosts").expect("Unable to read file");
println!("{}", data);
}
파일을 Vec<u8>
use std::fs;
fn main() {
let data = fs::read("/etc/hosts").expect("Unable to read file");
println!("{}", data.len());
}
파일 쓰기
use std::fs;
fn main() {
let data = "Some data!";
fs::write("/tmp/foo", data).expect("Unable to write file");
}
Rust 1.0 이상
These forms are slightly more verbose than the one-line functions that allocate a String
or Vec
for you, but are more powerful in that you can reuse allocated data or append to an existing object.
Reading data
Reading a file requires two core pieces: File
and Read
.
Read a file to a 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);
}
Read a file as a Vec<u8>
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());
}
Write a file
Writing a file is similar, except we use the Write
trait and we always write out bytes. You can convert a String
/ &str
to bytes with 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");
}
Buffered I/O
I felt a bit of a push from the community to use
BufReader
andBufWriter
instead of reading straight from a file
A buffered reader (or writer) uses a buffer to reduce the number of I/O requests. For example, it's much more efficient to access the disk once to read 256 bytes instead of accessing the disk 256 times.
That being said, I don't believe a buffered reader/writer will be useful when reading the entire file. read_to_end
seems to copy data in somewhat large chunks, so the transfer may already be naturally coalesced into fewer I/O requests.
Here's an example of using it for reading:
use std::fs::File;
use std::io::{BufReader, Read};
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);
}
And for writing:
use std::fs::File;
use std::io::{BufWriter, Write};
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");
}
A BufReader
is more useful when you want to read 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);
}
}
'developer tip' 카테고리의 다른 글
현재 실행중인 Linux 프로세스를 백그라운드에 배치하려면 어떻게해야합니까? (0) | 2020.08.19 |
---|---|
C #에서 첨부 파일이있는 이메일 보내기, 첨부 파일은 Thunderbird에서 Part 1.2로 도착합니다. (0) | 2020.08.19 |
CATALINA_OPTS 대 JAVA_OPTS-차이점은 무엇입니까? (0) | 2020.08.18 |
기본 .equals 및 .hashCode가 내 수업에서 어떻게 작동합니까? (0) | 2020.08.18 |
자바 스크립트로 CSS 값 변경 (0) | 2020.08.18 |