Я пытаюсь написать программу, которая сокращает файл до n строк.
У меня возникают трудности с подсчетом строк файла, а затем их перечислением. Использование одного итератора не работает, поскольку для него вызывается .count()
, который потребляет итератор. Однако создание двух отдельных буферов из файла дает аналогичные результаты?
let file_path = Path::new(&args[1]);
let file_result = OpenOptions::new().read(true).open(file_path);
let file = match file_result {
Ok(file) => file,
Err(error) => {
panic!("failed to open file: {}", error.to_string());
}
};
let lines_amount = BufReader::new(&file).lines().count();
if lines_amount == 0 {
panic!("The file has no lines");
}
println!("{}", lines_amount);
// this will not iterate, no matter the amount of lines in the file
for (i, line_result) in BufReader::new(&file).lines().enumerate() {
// ...
}
Открытие двух файлов и создание буфера из каждого дает одинаковые результаты.
Почему это происходит? Как мне прочитать количество строк в файле, а затем перебрать их?
@kotatsuyaki Должно быть, я сделал ошибку, когда проверял это тогда. Честно говоря, именно отсюда и возникла большая часть моего замешательства. Теперь понятно, как это работает, спасибо
Вы должны seek
переходить к началу между использованием File
, иначе вы продолжите чтение с того места, где остановился последний read
.
Здесь он немного скрыт, потому что Read
на &File
использует внутреннюю изменчивость и эквивалентен File
.
let file_path = Path::new(&args[1]);
let file_result = OpenOptions::new().read(true).open(file_path);
let mut file = match file_result {
Ok(file) => file,
Err(error) => {
panic!("failed to open file: {}", error.to_string());
}
};
let lines_amount = BufReader::new(&file).lines().count();
if lines_amount == 0 {
panic!("The file has no lines");
}
println!("{}", lines_amount);
// reset files position to start
file.seek( std::io::SeekFrom::Start(0));
for (i, line_result) in BufReader::new(&file).lines().enumerate() {
// ...
}
«Открытие двух файлов и создание буфера из каждого, кажется, дает одинаковые результаты» - нет, это не так. Открытие файла отдельно для подсчета строк и итерации работ, см. Пример площадки для игры на Rust.