在Rust中逐行读取大文件
我的Rust程序打算逐行读取一个非常大(高达几GB)的简单文本文件。问题是,此文件太大,无法立即读取,也无法将所有行传输到在Rust中逐行读取大文件,rust,Rust,我的Rust程序打算逐行读取一个非常大(高达几GB)的简单文本文件。问题是,此文件太大,无法立即读取,也无法将所有行传输到Vec 在Rust中处理此问题的惯用方法是什么?您想使用,尤其是函数: 您想使用,特别是功能: 请注意,新行被视为LF或CR后跟LF。如果文件大小大于可用大小,则这不一定是最有效的方法memory@Awalias我更新了我的答案以便更清楚。如果你不明白一些具体的东西,请告诉我什么。开始学习Rust,这是非常有用的信息。注意,新行被认为是LF或CR后跟LF。如果文件大小大于可用
Vec
在Rust中处理此问题的惯用方法是什么?您想使用,尤其是函数:
您想使用,特别是功能:
请注意,新行被视为LF或CR后跟LF。如果文件大小大于可用大小,则这不一定是最有效的方法memory@Awalias我更新了我的答案以便更清楚。如果你不明白一些具体的东西,请告诉我什么。开始学习Rust,这是非常有用的信息。注意,新行被认为是LF或CR后跟LF。如果文件大小大于可用大小,这不一定是最有效的方法memory@Awalias我更新了我的答案以便更清楚。如果你不明白一些具体的东西,请告诉我什么。开始学习生锈,这是非常有帮助的informative@Kroltan-没有那么多;根据谷歌在“rust中高效读取文件行”上的搜索,该页面现在是排名第一的条目。(:@HuwWalters这不是在发帖的时候!当前的读者将被引导到这些副本中的任何一个。而且我敢说,这样的帖子仍然符合“示例”的条件,所以评论仍然是最新的(:这是我的观点;这是一个有用的页面!(尽管讽刺可能有点平淡)我不同意这个问题已经得到了回答,当然不是通过现在的链接。OP特别要求为非常大的文件提供一种方法,其中文件太大,无法一次读取或逐行读取,必须存在一种更有效的方法,这使得此方法有效question@Kroltan-不太多;这一页现在是最热门的r根据谷歌在“rust中高效读取文件中的行”上的搜索,anking条目(-:@HuwWalters这不是发布时的内容!当前的读者将被定向到这些重复的内容中的任何一个。我敢说,这样的文章仍然符合“示例”的条件,因此评论仍然是最新的(-:这是我的观点;这是一个有用的页面!(讽刺的是可能有点平淡)我不同意这个问题已经得到了回答,当然不是通过现在的链接。OP特别要求对非常大的文件提供一种方法,其中文件太大,无法一次读取或逐行读取,必须存在一种更有效的方法,这使得这是一个有效的问题
use std::fs::File;
use std::io::{self, prelude::*, BufReader};
fn main() -> io::Result<()> {
let file = File::open("foo.txt")?;
let reader = BufReader::new(file);
for line in reader.lines() {
println!("{}", line?);
}
Ok(())
}
fn main() -> std::io::Result<()> {
let mut reader = my_reader::BufReader::open("Cargo.toml")?;
let mut buffer = String::new();
while let Some(line) = reader.read_line(&mut buffer) {
println!("{}", line?.trim());
}
Ok(())
}
mod my_reader {
use std::{
fs::File,
io::{self, prelude::*},
};
pub struct BufReader {
reader: io::BufReader<File>,
}
impl BufReader {
pub fn open(path: impl AsRef<std::path::Path>) -> io::Result<Self> {
let file = File::open(path)?;
let reader = io::BufReader::new(file);
Ok(Self { reader })
}
pub fn read_line<'buf>(
&mut self,
buffer: &'buf mut String,
) -> Option<io::Result<&'buf mut String>> {
buffer.clear();
self.reader
.read_line(buffer)
.map(|u| if u == 0 { None } else { Some(buffer) })
.transpose()
}
}
}
fn main() -> std::io::Result<()> {
for line in my_reader::BufReader::open("Cargo.toml")? {
println!("{}", line?.trim());
}
Ok(())
}
mod my_reader {
use std::{
fs::File,
io::{self, prelude::*},
rc::Rc,
};
pub struct BufReader {
reader: io::BufReader<File>,
buf: Rc<String>,
}
fn new_buf() -> Rc<String> {
Rc::new(String::with_capacity(1024)) // Tweakable capacity
}
impl BufReader {
pub fn open(path: impl AsRef<std::path::Path>) -> io::Result<Self> {
let file = File::open(path)?;
let reader = io::BufReader::new(file);
let buf = new_buf();
Ok(Self { reader, buf })
}
}
impl Iterator for BufReader {
type Item = io::Result<Rc<String>>;
fn next(&mut self) -> Option<Self::Item> {
let buf = match Rc::get_mut(&mut self.buf) {
Some(buf) => {
buf.clear();
buf
}
None => {
self.buf = new_buf();
Rc::make_mut(&mut self.buf)
}
};
self.reader
.read_line(buf)
.map(|u| if u == 0 { None } else { Some(Rc::clone(&self.buf)) })
.transpose()
}
}
}