我正在尝试将新行添加到文本文件的开头。我首先使用 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# 中查看关于同一主题的其他一些问题, Python , NodeJs , PHP , Bash和 C .
有几种不同权衡的解决方案:
将整个文件复制到内存中,写入你想要的数据,然后写入文件的其余部分。如果文件很大,这可能是一个糟糕的解决方案,因为它会使用大量内存,但可能适合小文件,因为它实现起来很简单。
使用缓冲区,大小与您要添加的文本相同。一次将文件的 block 复制到内存中,然后用前一个 block 覆盖它。通过这种方式,您可以将文件的内容与开头的新文本一起打乱。这可能比其他方法慢,但不需要分配大量内存。当进程没有删除文件的权限时,它也可能是最佳选择。但要小心:如果进程被中断,这种方法可能会使文件处于损坏状态。
将新数据写入临时文件,然后附加原始文件的内容。然后删除原来的并重命名临时文件。这是一个很好的解决方案,因为它将繁重的工作委托(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/