必须使用StandardOpenOption.APPEND和CREATE选项才能安全追加写入,需显式指定UTF-8编码转换字符串为字节数组,多线程环境下须配合文件锁或日志框架保障顺序性。

Java 中 Files.write() 本身不支持追加模式(它默认覆盖写入),要实现“在文件末尾安全写入变量数据”,必须配合 StandardOpenOption.APPEND,并注意避免多线程或并发写入导致的数据错乱。
必须使用 APPEND 选项,不能只靠 write() 默认行为
Files.write() 是一个便捷但“一次性”的写入方法,默认会清空目标文件再写入。若想追加,必须显式传入 StandardOpenOption.APPEND —— 同时建议加上 StandardOpenOption.CREATE,确保文件不存在时自动创建:
Files.write(path, data, StandardOpenOption.CREATE, StandardOpenOption.APPEND)- 如果省略
CREATE,而文件不存在,会抛出NoSuchFileException - 仅用
APPEND不保证线程安全;多个线程同时调用,可能产生内容交错(如两行数据混成一行)
写入前需将变量转为字节数组,注意编码一致性
Files.write() 接收 byte[],所以字符串变量必须明确编码转换,推荐用 StandardCharsets.UTF_8 避免平台默认编码差异:
- 正确:
Files.write(path, (str + "\n").getBytes(StandardCharsets.UTF_8), APPEND, CREATE) - 错误:
Files.write(path, str.getBytes())(依赖系统默认编码,Windows 和 Linux 可能不同) - 若变量是数字、对象等,先格式化为字符串(如
String.valueOf(num)或gson.toJson(obj)),再编码
高并发场景下,仅靠 APPEND 不够,需额外同步
即使用了 APPEND,JVM 层面的多次 Files.write() 调用仍可能被操作系统调度打乱顺序。安全做法是:
- 单线程环境:直接用带
APPEND的Files.write()即可 - 多线程/多进程环境:改用
FileChannel+FileLock,或用日志框架(如 Log4j/SLF4J)接管输出 - 简单替代:用
try-with-resources手动管理Files.newOutputStream()并加synchronized块(适合轻量级协调)
完整示例:安全追加一行带时间戳的变量数据
以下代码将字符串变量追加到文件末尾,每行独立,自动换行,UTF-8 编码,文件不存在则创建:
String content = "user_id=123, score=" + score + ", ts=" + System.currentTimeMillis();
byte[] line = (content + "\n").getBytes(StandardCharsets.UTF_8);
Files.write(Paths.get("log.txt"), line,
StandardOpenOption.CREATE, StandardOpenOption.APPEND);
注意:该示例适用于低频写入;高频或关键日志应考虑缓冲、异步写入或专用日志库。

















