파일 읽기
이제는 file_path
인수에 명시된 파일을 읽는 기능을 추가해 보겠습니다.
우선 테스트에 사용할 샘플 파일이 필요합니다: 여러 줄의 몇 개의 반복된
단어들로 구성된 작은 양의 텍스트로 된 파일을 사용하겠습니다. 예제 12-3은
딱 맞게 사용될 에밀리 딕킨슨 (Emily Dickinson) 의 시가 있습니다! 프로젝트의
루트 레벨에 poem.txt이라는 이름의 파일을 만들고, 시 ‘I’m Nobody! Who are
you?’를 입력하세요.
파일명: poem.txt
I'm nobody! Who are you?
Are you nobody, too?
Then there's a pair of us - don't tell!
They'd banish us, you know.
How dreary to be somebody!
How public, like a frog
To tell your name the livelong day
To an admiring bog!
텍스트를 채워 넣었다면 예제 12-4처럼 src/main.rs에 파일을 읽는 코드를 추가하세요.
파일명: src/main.rs
use std::env;
use std::fs;
fn main() {
// --생략--
let args: Vec<String> = env::args().collect();
let query = &args[1];
let file_path = &args[2];
println!("Searching for {}", query);
println!("In file {}", file_path);
let contents = fs::read_to_string(file_path)
.expect("Should have been able to read the file");
println!("With text:\n{contents}");
}
먼저 use
구문을 사용하여 표준 라이브러리의 연관된 부분을 가져옵니다:
파일을 다루기 위해서는 std::fs
가 필요하죠.
main
에서 새로운 구문 fs::read_to_string
이 file_path
를 받아서 그
파일을 열고, 파일 내용물의 std::io::Result<String>
을 반환합니다.
그다음 다시 한번 임시로 println!
구문을 추가하여 파일을 읽은 후
contents
의 값을 출력하는 것으로 현재까지의 프로그램이 잘 작동하는지
확인합니다.
첫 번째 커맨드 라인 인수에는 아무 문자열이나 넣고 (아직 검색 부분은 구현하지 않았으므로) 두 번째 인수에는 poem.txt 파일을 넣어서 이 코드를 실행해 봅시다:
$ cargo run -- the poem.txt
Compiling minigrep v0.1.0 (file:///projects/minigrep)
Finished dev [unoptimized + debuginfo] target(s) in 0.0s
Running `target/debug/minigrep the poem.txt`
Searching for the
In file poem.txt
With text:
I'm nobody! Who are you?
Are you nobody, too?
Then there's a pair of us - don't tell!
They'd banish us, you know.
How dreary to be somebody!
How public, like a frog
To tell your name the livelong day
To an admiring bog!
훌륭해요! 코드가 파일의 내용물을 읽은 뒤 출력했습니다. 하지만 이 코드에는
몇 가지 결점이 있습니다. 현재 main
함수에는 여러 가지 기능이 있습니다:
일반적으로 함수 하나당 단 하나의 아이디어에 대한 기능을 구현할 때
함수가 더 명료해지고 관리하기 쉬워집니다. 또 한 가지 문제는 처리 가능한
수준의 에러 처리를 안 하고 있다는 점입니다. 프로그램은 아직 작고,
따라서 이러한 결점이 큰 문제는 아니지만, 프로그램이 커지면 이 문제들을
깔끔하게 고치기 어려워질 것입니다. 작은 양의 코드를 리팩터링하는 것이 훨씬
쉽기 때문에, 프로그램을 개발할 때 일찍 리팩터링하는 것은 좋은 관행입니다.
이걸 바로 다음에 하겠습니다.