Почему я не могу перебирать строки файла после их подсчета?

Я пытаюсь написать программу, которая сокращает файл до 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() {
    // ...
}

Открытие двух файлов и создание буфера из каждого дает одинаковые результаты.

Почему это происходит? Как мне прочитать количество строк в файле, а затем перебрать их?

«Открытие двух файлов и создание буфера из каждого, кажется, дает одинаковые результаты» - нет, это не так. Открытие файла отдельно для подсчета строк и итерации работ, см. Пример площадки для игры на Rust.

kotatsuyaki 03.12.2022 15:39

@kotatsuyaki Должно быть, я сделал ошибку, когда проверял это тогда. Честно говоря, именно отсюда и возникла большая часть моего замешательства. Теперь понятно, как это работает, спасибо

Jonas Grønbek 03.12.2022 16:27
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
102
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы должны 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() {
    // ...
}

Другие вопросы по теме