Я попытался прочитать файл способом, который достаточно эффективен для моей цели. У меня есть список идентификаторов файлов, имен и индексов строк (упорядоченных), и для каждой пары (file_id, file_name, line_index)
мне нужно открыть файл, найти строку по индексу и распечатать.
Чтобы быть более производительным (я знаю, что ввод упорядочен), я хотел бы кэшировать BufReader
, который читается построчно, и пусть файл остается открытым, если это возможно.
fn main() {
// positions in file
// structure: (file_id, file_name, line_index_in_file)
let positions = &vec![
(1, String::from("file1"), 1),
(1, String::from("file1"), 2),
(1, String::from("file1"), 20),
(2, String::from("file2"), 15)];
print_lines_from_file(&positions);
}
fn print_lines_from_file(found: &Vec<(i32, String, i32)>) {
let mut last_file_id = -1;
//let mut last_file_name = None;
let mut open_file = None;
let mut open_reader = None;
for &(file_id, ref file_name, pos_in_file) in found {
println!("{} {}", file_id, pos_in_file);
if last_file_id < file_id {
last_file_id = file_id;
//last_file_name = file_ids.get(&file_id);
if let Some(to_close) = open_file {
drop(open_reader.unwrap());
drop(to_close);
}
//let file = File::open(last_file_name.unwrap()).unwrap();
let file = File::open(file_name).unwrap();
open_file = Some(file);
open_reader = Some(BufReader::new(&file));
}
// use reader to find the line in file and process
}
}
Я столкнулся с этой проблемой:
main.rs:40:48: 40:52 error: `file` does not live long enough
main.rs:40 open_reader = Some(BufReader::new(&file));
main.rs:40:48: 40:52 error: use of moved value: `file` [E0382]
main.rs:40 open_reader = Some(BufReader::new(&file));
Это очевидно (время жизни file
очень короткое), но я не знаю, как это обойти. BufReader
зависит от File
, но мне нужно закрыть File
позже в цикле, когда file_id
изменится.
Также мне не очень удобно вызывать drop
таким образом в цикле, так как мне кажется, что я пытаюсь обмануть компилятор. Такой подход подходит?
Пожалуйста, даже если вы знаете лучшее решение (например, как закрыть файл через BufReader
, я был бы признателен за общее понимание того, как это решить).