【问题标题】:How to completely remove a line from a file?如何从文件中完全删除一行?
【发布时间】:2022-01-12 01:21:38
【问题描述】:

如何在 Rust 中完全删除一行?不只是用空行替换它。

在Rust中,当你从文件中删除一行时,以如下代码为例:

let mut file: File = File::open("file.txt").unwrap();
let mut buf = String::from("");
file.read_to_string(&mut buf).unwrap(); //Read the file to a buffer
let reader = BufReader::new(&file);

for (index, line) in reader.lines().enumerate() { //Loop through all the lines in the file
    if line.as_ref().unwrap().contains("some text") { //If the line contains "some text", execute the block
        buf = buf.replace(line.as_ref().unwrap(), ""); //Replace "some text" with nothing
    }
}
file.write_all(buf.as_bytes()).unwrap(); //Write the buffer back to the file

file.txt:

random text
random text
random text
some text
random text
random text

当你运行代码时,file.txt 变成这样:

random text
random text
random text

random text
random text

不仅仅是

random text
random text
random text
random text
random text

有什么方法可以完全删除该行而不是将其留空?像某种特殊字符?

【问题讨论】:

    标签: file text rust


    【解决方案1】:

    这部分是坏消息:buf = buf.replace(line.as_ref().unwrap(), ""); 这是在整个缓冲区中搜索以查找行内容(不带'\n')并将其替换为""。要使其行为符合您的预期,您需要添加回换行符。你可以通过buf.replace(line.as_ref().unwrap() + "\n", "") 做到这一点。问题是lines() 将不止“\n”视为换行符,它也会在“\r\n”上拆分。如果你知道你总是使用 "\n" 或 "\r\n" 作为换行符,你可以解决这个问题 - 如果不是,你将需要比 lines() 更狡猾的东西。

    但是,还有一个更棘手的问题。对于较大的文件,这可能最终会扫描字符串并多次调整其大小,从而给出O(N^2) 样式行为,而不是预期的O(N)。此外,需要将整个文件读入内存,这对于非常大的文件可能是不利的。

    O(N^2) 和内存问题的最简单解决方案是逐行进行处理,并且 然后将新文件移动到位。它看起来像这样。

    //Scope to ensure that the files are closed
    {
        let mut file: File = File::open("file.txt").unwrap();
        let mut out_file: File = File::open("file.txt.temp").unwrap();
    
        let reader = BufReader::new(&file);
        let writer = BufWriter::new(&out_file);
    
        for (index, line) in reader.lines().enumerate() {
           let line = line.as_ref().unwrap();
           if !line.contains("some text") {
               writeln!(writer, "{}", line);
           }
       }
    }
    fs::rename("file.txt.temp", "file.txt").unwrap();
    

    这仍然不能正确处理跨平台换行符,因为你需要一个更智能的行迭代器。

    【讨论】:

      【解决方案2】:

      嗯可以尝试删除上一行中的新行字符

      【讨论】:

        猜你喜欢
        • 2012-05-22
        • 2015-05-02
        • 2022-08-18
        • 2011-03-28
        • 1970-01-01
        • 1970-01-01
        • 2017-02-16
        • 1970-01-01
        相关资源
        最近更新 更多