file - 写入文件时,OpenOptions write 无法正常工作
问题描述
所以我通过在 rust 中制作一个简单的 cat/bat 克隆来学习 rust,而且我似乎无法覆盖文件。
代码:
use std::{fs::*, io::{Read, Write}};
fn main() {
let mut file = OpenOptions::new()
.read(true)
.write(true)
.open("foo.txt")
.unwrap();
let mut contents = String::new();
let mut formatted = String::new();
file.read_to_string(&mut contents).unwrap();
let mut i = 0;
let mut formatted_line:String;
for line in contents.split("\n") {
formatted_line = format!("{}| {}",i,line);
formatted.push_str(&formatted_line);
i += 1;
}
file.write_all(formatted.as_bytes()).unwrap();
}
foo.txt 之前:
test
foo
bar
foo.txt 之后:
test
foo
bar0| test
1| foo
2| bar
根据我所阅读的内容以及以下文档中的内容fs.rs:747-748
:
/// If the file already exists, any write calls on it will overwrite its
/// contents, without truncating it.
该.write(true)
选项指定覆盖文件内容,并且该.append(true)
选项附加到现有内容。但是从我编写的代码来看,程序忽略了写入 OpenOption,并附加到文件内容。我还尝试.append(false)
了 OpenOptions 和相同的输出。
我使用的是 Windows 10 Home,而 foo.txt 是一个没有任何特殊权限或限制的 txt 文件。
Rust / Cargo 版本:
rustc 1.55.0 (c8dfcfe04 2021-09-06)
cargo 1.55.0 (32da73ab1 2021-08-23)
解决方案
也许你最好使用简单的 fs::*,我知道,OpenOptions 如果你将创建多进程/线程代码,这个函数将面临竞争,所以可能(据我了解:读取所有然后删除所有并写入):
use std::fs::{File, write};
use std::io::Result;
fn main() -> Result<()>{
let mut file = File::open("foo.txt")?;
//Read(create copy if you need something simultaneous read before)
// file.try_clone()?;//simply, both files changes
file.read_to_end(&mut your_string_or_vec)?;
//..... Your code
//and then truncate all
file_copy.set_len(0)?;
write("foo.txt", formatted.as_bytes())?;
}
另一种获取临时文件的方法(一个位置不重要(std::env::temp_dir()
))
use std::fs::{File, write};
use tempfile::NamedTempFile;
use std::io:: Result;
fn main() -> Result<()>{
let mut read_from_file = String::new();
let mut formatted = String::new();
read_from_file = fs::read_to_string("foo.txt")?.parse()?;
for line in read_from_file.split("\n") {
formatted_line = format!("{}| {}",i,line);
formatted.push_str(&formatted_line);
i += 1;
}
let mut file_tmp1 = NamedTempFile::new()?;
println!("Let's write into temporary {:?}", file.path());
let mut file_tmp2 = file_tmp1.reopen()?;
writeln!(file_tmp1, formatted)?;
let mut buf = String::new();
file_tmp2.read_to_string(&mut buf)?;
fs::write("foo.txt",buf.as_bytes())?;
file_tmp1.close()?;
file_tmp2.close()?;
推荐阅读
- c++11 - 移动构造函数注释未打印
- css - flexbox 项目的图像和文本与绝对定位的 div 重叠(工具提示)
- oracle-cloud-infrastructure - oci java sdk 通过代理
- c# - Unity 2018 C# - Fbx 使用输入运行动画缩放?
- javascript - 结合 ReactJS + Marzipano 时出现白屏?
- service-worker - 缓存在相对路径下的缓存存储中的项目
- java - HttpsURLConnection 身份验证器错误
- javascript - 如何从 redux-persist 中删除所有条目
- javascript - JavaScript 添加多个十进制数并在 0.59 后舍入该值
- vba - Excel VBA:引用 Worksheet.Cells() 中的列索引