当前位置: 首页 > 知识库问答 >
问题:

这是从文件中读取行并将它们拆分为单词的正确方法吗?

刘棋
2023-03-14

编者按:此代码示例来自1.0之前的Rust版本,在语法上无效的Rust 1.0代码。此代码的更新版本会产生不同的错误,但答案仍然包含有价值的信息。

我实现了以下方法来从2维数据结构中的文件中返回单词:

fn read_terms() -> Vec<Vec<String>> {
    let path = Path::new("terms.txt");
    let mut file = BufferedReader::new(File::open(&path));
    return file.lines().map(|x| x.unwrap().as_slice().words().map(|x| x.to_string()).collect()).collect();
}

这是正确的、惯用的、有效的防锈方法吗?我想知道是否需要经常调用collect(),是否需要调用来分配内存。也许应该对返回类型进行不同的定义,以便更惯用、更高效?


共有2个答案

孟晋
2023-03-14

相反,您可以将整个文件作为单个String读取,然后构建指向其中单词的引用结构:

use std::io::{self, Read};
use std::fs::File;

fn filename_to_string(s: &str) -> io::Result<String> {
    let mut file = File::open(s)?;
    let mut s = String::new();
    file.read_to_string(&mut s)?;
    Ok(s)
}

fn words_by_line<'a>(s: &'a str) -> Vec<Vec<&'a str>> {
    s.lines().map(|line| {
        line.split_whitespace().collect()
    }).collect()
}

fn example_use() {
    let whole_file = filename_to_string("terms.txt").unwrap();
    let wbyl = words_by_line(&whole_file);
    println!("{:?}", wbyl)
}

这将以更少的开销读取文件,因为它可以将其读入单个缓冲区,而使用BufReader读取行意味着大量复制和分配,首先是将其读入BufReader内部的缓冲区,然后将其读入新分配的字符串,然后将其读入新分配的字符串中。它还将使用更少的内存,因为单个大型字符串和引用向量比许多单个字符串更紧凑。

一个缺点是不能直接返回引用的结构,因为它不能超过存放单个大字符串的堆栈框架。在上面的example_use中,我们必须将大的字符串放入let中,以便按行调用单词。可以使用不安全的代码,并将字符串和引用包装到私有结构中来解决这个问题,但这要复杂得多。

彭浩穰
2023-03-14

从文本文件中获取单词有一种更短、更可读的方法。

use std::io::{BufRead, BufReader};
use std::fs::File;

let reader = BufReader::new(File::open("file.txt").expect("Cannot open file.txt"));

for line in reader.lines() {
    for word in line.unwrap().split_whitespace() {
        println!("word '{}'", word);
    }
}
 类似资料:
  • 问题内容: 我有以下问题:我有一个近500mb的文件。它的文字全部排成一行。文本以虚拟行结尾分隔,称为ROW_DEL,并在文本中如下所示: 现在我需要进行以下操作,我想将此文件分成几行,这样我得到一个文件: 这个问题,即使我使用Windows文本编辑器将其打开,也会由于文件太大而中断。 是否可以像我在C#,Java或Python中提到的那样拆分此文件?什么是最好的灵魂,不要过度杀伤我的CPU。 问

  • 问题内容: 我有一个文件,我想用Java读取并将其拆分为(用户输入)输出文件。这是我读取文件的方式: 如何将文件拆分为文件? 注意-由于文件中的条目数约为100k,因此我无法将文件内容存储到数组中,然后将其拆分并保存到多个文件中。 问题答案: 由于一个文件可能很大,因此每个拆分文件也可能很大。 例: 源文件大小:5GB 数字分割:5:目的地 档案大小:每个1GB(5个档案) 即使我们有这样的内存,

  • 问题内容: 我已经解决了这些问题,但似乎仍然无法解决。我有一个文本文件,分为几行。每行包含5个数据,中间用“,”分隔。我正在尝试读取此文件并将信息拆分为以下形式的字符串数组: 请有人可以帮我解决一个简单的解决方案!?谢谢!!!:) 数据示例: 样例代码: 公共无效的readFile(){ 错误 07-24 06:26:56.524:E / AndroidRuntime(27203):致命例外:主要

  • 问题内容: 我有一个非常大的CSV文件(超过1GB),它有100,000行。 我需要编写一个Java程序来解析CSV文件中的每一行,以创建用于发送HTTP请求的正文。 换句话说,我需要发出100,000个与CSV文件中的行相对应的HTTP请求。如果我在单个线程中执行这些操作将非常漫长。 我想创建1,000个线程,以执行以下操作:i)从CSV文件读取一行,ii)创建一个HTTP请求,该请求的正文包含

  • 我能够使用StringTokenizer正确地拆分,但在令牌形成后无法访问单个元素。尝试使用array.split(),但它没有将值拆分为单独的数组值。请帮帮我。提前谢了。 我的代码

  • 问题内容: 使用GoogleAppEngine(Go)读取文件的正确方法是什么? 在Java中,我读到了,是否有等效的功能? 问题答案: 您可以从App Engine上的文件中读取文件,也可以从计算机上运行的Go应用程序中的文件中读取文件。 注意事项: 您应该使用 相对 文件路径,而不是绝对路径。工作目录是应用程序的根文件夹(文件所在的位置)。 Go代码只能读取属于 应用程序 文件的文件,因此,如