Files.copy() 抛 NoSuchFileException 时需先用 Files.createDirectories() 创建目标父目录,并显式传入 StandardCopyOption.REPLACE_EXISTING 才能覆盖;避免字符串拼接路径,应使用 Paths.get()。

Files.copy() 复制文件时抛出 NoSuchFileException 怎么办
不是源文件路径写错,就是目标目录不存在。Java 的 Files.copy() 默认不会自动创建父目录,哪怕目标路径里有好几层嵌套文件夹。
- 先用
Files.createDirectories()确保目标路径的父目录存在,再调用copy() - 如果想“覆盖”已存在的目标文件,必须显式传入
StandardCopyOption.REPLACE_EXISTING,否则默认抛FileAlreadyExistsException - 避免用字符串拼接路径,改用
Paths.get("a", "b", "c.txt"),跨平台更稳
Path source = Paths.get("data/input.log");
Path target = Paths.get("backup/logs/input.log");
Files.createDirectories(target.getParent()); // 关键:先建好 backup/logs
Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
用 Files.walk() 遍历大目录卡死或内存爆掉
Files.walk() 返回的是一个惰性流(Stream),但如果你在终端操作里用了 .collect(Collectors.toList()),整个目录树会一次性加载进内存——几万个小文件就可能 OOM。
- 务必配合
try-with-resources使用,防止底层DirectoryStream泄漏 - 遍历时加
.filter(Files::isRegularFile)排除目录和符号链接,避免误处理 - 需要深度限制?用
Files.walk(start, maxDepth),比如只查两层子目录就传2
try (Streamstream = Files.walk(Paths.get("project/src"), 3)) { stream.filter(Files::isRegularFile) .filter(p -> p.toString().endsWith(".java")) .forEach(System.out::println); }
Files.write() 写中文乱码,或者换行符在 Windows/Linux 上不一致
Files.write() 默认用 UTF-8 编码,但没指定 Charset 参数时,某些旧 JDK(如 8u202 之前)可能退化为系统默认编码;换行符则完全依赖你传入的字符串里是 "\n" 还是 "\r\n"。
一套面向小企业用户的企业网站程序!功能简单,操作简单。实现了小企业网站的很多实用的功能,如文章新闻模块、图片展示、产品列表以及小型的下载功能,还同时增加了邮件订阅等相应模块。公告,友情链接等这些通用功能本程序也同样都集成了!同时本程序引入了模块功能,只要在系统默认模板上创建模块,可以在任何一个语言环境(或任意风格)的适当位置进行使用!
- 强制指定编码:用
StandardCharsets.UTF_8作为第三个参数 - 写多行内容时,别手拼
"line1\nline2",改用Files.write(path, lines, charset, options),它会自动按当前系统规范换行 - 追加写入要加
StandardOpenOption.APPEND,否则默认覆盖
Listcontent = Arrays.asList("你好", "world", "第三行"); Files.write(Paths.get("out.txt"), content, StandardCharsets.UTF_8, StandardOpenOption.CREATE, StandardOpenOption.APPEND);
Files.delete() 删除非空目录直接失败
Files.delete() 只删空目录或单个文件,遇到非空目录立刻抛 DirectoryNotEmptyException。这不是 bug,是设计如此——NIO 要求你明确表达“我要递归删”的意图。
立即学习“Java免费学习笔记(深入)”;
- 删整个目录树,用
Files.walkFileTree()配合自定义SimpleFileVisitor - 别自己写递归 delete,容易漏掉权限问题或符号链接循环
- JDK 14+ 提供了
Files.deleteIfExists(),但依然不支持非空目录,别被名字误导
Files.walkFileTree(dir, new SimpleFileVisitor真正难的不是记住每个方法名,而是每次调用前下意识问一句:这个路径是否存在?它的父级是否可写?我有没有关掉流?NIO 的链式调用看着干净,但每一步都藏着隐式约束。() { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { Files.delete(file); return FileVisitResult.CONTINUE; } @Override public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { if (exc == null) Files.delete(dir); return FileVisitResult.CONTINUE; } });









