我正在尝试在文本文件的开头添加一个新行。我首先使用 append 打开文件,但这仅允许我使用 write_all 写入文件末尾,至少这是我得到的结果。如果我正确阅读了文档,这是设计使然。

我试过玩 seek ,但这并没有解决它。

这是我目前所拥有的:

let mut file = OpenOptions::new().append(true).open(&file_path).unwrap();
file.seek(SeekFrom::Start(0));
file.write_all(b"Cool days\n");

如果我用 write 打开文件,我最终会覆盖数据而不是添加数据。使用 Rust 完成此任务的合适方法是什么?

最佳答案

你不能用任何编程语言直接做到这一点。在 C#PythonNodeJsPHPBashC 中查看有关同一主题的其他一些问题。

有几种具有不同权衡的解决方案:

  • 将整个文件复制到内存中,写入你想要的数据,然后在它之后写入文件的其余部分。如果文件很大,这可能是一个糟糕的解决方案,因为它将使用大量内存,但可能适用于小文件,因为它易于实现。
  • 使用缓冲区,大小与要添加的文本相同。一次将文件的块复制到内存中,然后用前一个块覆盖它。通过这种方式,您可以将文件的内容与开头的新文本一起打乱。这可能比其他方法慢,但不需要大量内存分配。当进程没有删除文件的权限时,它也可能是最佳选择。但要小心:如果进程中断,这种方法可能会使文件处于损坏状态。
  • 将新数据写入临时文件,然后追加原始内容。然后删除原始文件并重命名临时文件。这是一个很好的解决方案,因为它将繁重的工作委托(delegate)给操作系统,并且原始数据已备份,因此如果进程中断,则不会损坏。

  • 从 Stack Overflow 上搜索,第三个解决方案似乎是其他语言最受欢迎的答案,例如in Bash 。这可能是因为它快速、安全并且通常只需几行代码即可实现。

    一个快速的 Rust 版本看起来像这样:
    extern crate mktemp;
    use mktemp::Temp;
    use std::{fs, io, io::Write, fs::File, path::Path};
    
    fn prepend_file<P: AsRef<Path>>(data: &[u8], file_path: &P) -> io::Result<()> {
        // Create a temporary file
        let mut tmp_path = Temp::new_file()?;
        // Stop the temp file being automatically deleted when the variable
        // is dropped, by releasing it.
        tmp_path.release();
        // Open temp file for writing
        let mut tmp = File::create(&tmp_path)?;
        // Open source file for reading
        let mut src = File::open(&file_path)?;
        // Write the data to prepend
        tmp.write_all(&data)?;
        // Copy the rest of the source file
        io::copy(&mut src, &mut tmp)?;
        fs::remove_file(&file_path)?;
        fs::rename(&tmp_path, &file_path)?;
        Ok(())
    }
    

    用法:
    fn main() -> io::Result<()> {
        let file_path = Path::new("file.txt");
        let data = "Data to add to the beginning of the file\n";
        prepend_file(data.as_bytes(), &file_path)?;
        Ok(())
    }
    

    关于file - 在文件开头添加一行,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43441166/

    10-10 14:40
    查看更多