Rust写入txt日志文件时如何避免覆盖数据实现追加写入
问题原因
代码存在两个核心错误,导致日志始终被覆盖:
std::fs::File::create接口的固有逻辑是:如果目标文件已存在,会直接将文件截断为空(清空所有旧内容),每次循环执行到这行时,之前写入的日志已经被删掉,后续写入自然只会保留最后一次的记录。- 调用的
.append(true)并不是File实例的方法,追加模式属于文件打开时的配置参数,不能在create执行完、文件已经被清空之后再设置。另外代码还存在路径大小写不一致的问题:先创建的是Logs目录,打开文件时写的却是logs/Logs.txt,在大小写敏感的Linux/macOS系统上会直接触发路径不存在的错误。
修正方法
用std::fs::OpenOptions显式配置文件打开参数,替代直接调用File::create,明确指定追加写入、不存在则创建的规则,同时统一日志路径写法。
修正后的日志写入相关代码如下:
let download_dir = Path::new(download_dir); fs::create_dir_all(download_dir).unwrap(); fs::rename(&path, download_dir.join(file_name)).unwrap(); let log_dir = "Logs"; fs::create_dir_all(log_dir).unwrap(); // 替换原来的File::create逻辑,正确配置追加模式 let mut file = std::fs::OpenOptions::new() .create(true) // 文件不存在时自动创建 .append(true) // 所有写入内容自动追加到文件末尾,不清空原有内容 .write(true) // 授予文件写入权限 .open("Logs/Logs.txt") // 和上方创建的Logs目录路径保持一致 .expect("open log file failed"); file.write_all(format!("{:?}", file_name).as_bytes()).expect("write failed"); file.write_all(format!(" Moved to ").as_bytes()).expect("write failed"); file.write_all(format!("{:?}\n", download_dir.display()).as_bytes()).expect("write failed");
如果追求更高的IO效率,也可以把日志文件的打开逻辑移到for循环外部,整个循环过程只打开一次文件,循环内重复执行写入操作即可,避免每次迭代都重复开关文件的性能损耗。
内容的提问来源于stack exchange,提问作者user18240098
相关产品推荐
相关产品推荐

