filealreadyexistsexception 是 files.createfile() 在目标路径已存在文件(非目录)时抛出的受检异常,表示同名文件已存在,拒绝创建且不覆盖;其设计意图是严格新建,不可用于“存在则跳过”的控制流。

FileAlreadyExistsException 是什么错误
这是 Files.createFile() 在目标路径已存在文件(非目录)时抛出的受检异常。不是“文件正在被占用”或“权限不足”,而是明确告诉你:那个名字的文件已经躺在那里了。
常见错误现象:java.nio.file.FileAlreadyExistsException: /tmp/data.txt —— 你调用 createFile() 想新建,但系统发现同名文件已存在,直接拒绝创建,不覆盖、不提示、不静默跳过。
为什么不用 createFile() 做“存在则跳过”逻辑
Files.createFile() 的设计意图就是“严格新建”,它不接受任何覆盖或忽略语义。想靠 try-catch 吞掉这个异常来实现“存在就不管”,虽然能跑通,但属于反模式:
- 异常用于异常流程,不是控制流;高频触发时性能差(JVM 抛异常开销大)
- 掩盖真实问题:比如本该是临时文件却反复撞名,说明生成逻辑有缺陷
- 无法区分“文件存在”和“其他 I/O 错误”(如磁盘满),全塞进同一个 catch 里容易误判
更稳妥的替代方案:先检查再创建
用 Files.exists() 预判,再决定是否调用 createFile() —— 简单、明确、无副作用:
本文档主要讲述的是用Apache Spark进行大数据处理——第一部分:入门介绍;Apache Spark是一个围绕速度、易用性和复杂分析构建的大数据处理框架。最初在2009年由加州大学伯克利分校的AMPLab开发,并于2010年成为Apache的开源项目之一。 在这个Apache Spark文章系列的第一部分中,我们将了解到什么是Spark,它与典型的MapReduce解决方案的比较以及它如何为大数据处理提供了一套完整的工具。希望本文档会给有需要的朋友带来帮助;感
立即学习“Java免费学习笔记(深入)”;
Path path = Paths.get("/tmp/data.txt");
if (!Files.exists(path)) {
Files.createFile(path);
}
注意点:
-
Files.exists()默认不跟随符号链接,如果路径可能是软链且你关心的是链指向的目标是否存在,加LinkOption.NOFOLLOW_LINKS - 这个方案仍有微小时间窗口:检查完、创建前,另一个线程/进程可能抢先建好同名文件,此时
createFile()还是会抛FileAlreadyExistsException—— 所以生产代码里仍建议保留一层兜底 try-catch,只捕获这一个异常,其余异常不该吞 - 别用
file.exists()(java.io.File),它对某些文件系统(如 NFS)返回结果不可靠,Files.exists()是 NIO.2 的标准行为,更健壮
如果真需要“原子性覆盖创建”,别用 createFile()
Files.createFile() 从不覆盖,也做不到原子覆盖。要实现“不存在则建,存在则替换并保证写入完整”,得换路子:
- 用
Files.write(path, data, StandardOpenOption.CREATE, StandardOpenOption.WRITE)—— 它默认覆盖,且支持StandardOpenOption.TRUNCATE_EXISTING显式声明截断语义 - 若需严格“先建空文件再写内容”,可用
Files.createTempFile()写完再Files.move(temp, target, StandardCopyOption.REPLACE_EXISTING),move 在同一文件系统下是原子的 - 注意
REPLACE_EXISTING不会覆盖正在被其他进程打开写入的文件(Windows 下尤其敏感),失败时抛AccessDeniedException,不是FileAlreadyExistsException
真正难处理的从来不是“文件存在”,而是“存在但状态未知”——比如它正被日志框架锁定、是只读挂载下的残留、或权限位异常。这时候绕过异常去硬覆盖,大概率埋雷。









