如何正确移动文件避免 NoSuchFileException 错误
发布时间 - 2026-02-02 00:00:00 点击率:次本文详解因重复调用 `files.move()` 导致 `nosuchfileexception` 的根本原因,并提供结构清晰、资源安全的文件分类移动方案,确保 csv 文件仅被移动一次且 filereader 正确自动关闭。
在使用 Java NIO 的 Files.move() 处理批量 CSV 文件时,出现 java.nio.file.NoSuchFileException 是一个典型逻辑错误——并非文件路径错误,而是同一文件被多次移动。从您提供的代码可见:内层 for (CsvLine item : beans) 循环中,一旦匹配到 item.getValue() 为 2/43/32,便立即执行一次 Files.move(..., invalid_files);但循环并未终止,后续迭代会再次尝试对已被移走的原始文件调用 Files.move(),从而触发 NoSuchFileException。
更严重的是,原代码中存在两处 br.close() 手动调用(分别在 invalid 和 processed 分支),而 FileReader 已被声明在 try-with-resources 中,手动关闭不仅冗余,还可能引发 IllegalStateException。
✅ 正确做法是:
- 只移动一次文件:在解析完全部 CSV 行后,统一决定目标目录;
- 利用 try-with-resources 自动管理资源:彻底移除所有手动 close();
- 提前标记 + 统一移动:用 moveTo 变量动态指向 invalid_files 或 processed,最后单次执行 Files.move()。
以下是重构后的健壮实现:
@Override
public void execute(JobExecutionContext context) {
File directoryPath = new File("C:\\csv\\nov");
// 创建 processed 和 invalid_files 子目录(幂等)
Path processedDir = Path.of(directoryPath.getAbsolutePath(), "processed");
Path invalidDir = Path.of(directoryPath.getAbsolutePath(), "invalid_files");
try {
Files.createDirectories(processedDir);
Files.createDirectories(invalidDir);
} catch (IOException e) {
throw new RuntimeException("Failed to create directories", e);
}
// 过滤 CSV 文件
FilenameFilter csvFilter = (dir, name) -> name.toLowerCase().endsWith(".csv");
File[] csvFiles = directoryPath.listFiles(csvFilter);
if (csvFiles == null) {
System.out.println("No CSV files found.");
return;
}
for (File file : csvFiles) {
Path originalPath = file.toPath();
Path moveTo = processedDir.resolve(originalPath.getFileName()); // 默认移至 processed
try (FileReader br = new FileReader(file, StandardCharsets.UTF_16)) {
List beans = new CsvToBeanBuilder(br)
.withType(CsvLine.class)
.withSeparator('\t')
.withSkipLines(3)
.build()
.parse();
// 检查任意一行是否含非法值 →
标记为 invalid
for (CsvLine item : beans) {
Integer value = item.getValue();
if (value != null && (value.equals(2) || value.equals(43) || value.equals(32))) {
moveTo = invalidDir.resolve(originalPath.getFileName());
System.out.printf("⚠️ Invalid value %d found in %s → will move to invalid_files%n",
value, file.getName());
break; // 关键:跳出循环,避免重复判断和移动
}
}
} catch (Exception e) {
// 解析失败视为异常文件(如编码错误、格式损坏)
System.err.printf("❌ Parsing failed for %s: %s%n", file.getName(), e.getMessage());
moveTo = invalidDir.resolve(originalPath.getFileName());
}
// ✅ 统一、安全地执行移动(仅一次!)
try {
Files.move(originalPath, moveTo, StandardCopyOption.REPLACE_EXISTING);
System.out.printf("✅ Moved %s → %s%n", originalPath.getFileName(), moveTo.getParent().getFileName());
} catch (IOException e) {
throw new RuntimeException("Failed to move file: " + originalPath, e);
}
}
} ? 关键改进说明:
- break 不可省略:确保发现首个非法值即退出循环,防止二次移动;
- createDirectories() 替代 createDirectory():自动创建父目录(即使 invalid_files 上级不存在);
- 空指针防护:item.getValue() 判空避免 NullPointerException;
- 异常兜底策略:CSV 解析失败时也归入 invalid_files,提升鲁棒性;
- 日志语义清晰:区分 ⚠️ Invalid value、❌ Parsing failed、✅ Moved,便于问题追踪。
? 额外建议:
- 生产环境应使用 SLF4J/Logback 替代 System.out;
- 对大文件,可考虑流式校验(不全量加载 beans),进一步优化内存;
- 移动前可先 Files.exists(originalPath) 双重校验(虽非必需,但增强防御性)。
遵循此模式,即可彻底规避 NoSuchFileException,实现安全、可维护的文件分类处理流程。
# java
# 编码
# csv
# ai
# logback
# nio
# for
# try
# break
# 循环
# 指针
# 空指针
# 重构
# 已被
# 的是
# 是一个
# 不存在
# 首个
# 不全
# 还可能
# 两处
# 移除
# 根本原因
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
Java类加载基本过程详细介绍
JavaScript如何实现音频处理_Web Audio API如何工作?
昵图网官方站入口 昵图网素材图库官网入口
如何快速搭建高效可靠的建站解决方案?
大型企业网站制作流程,做网站需要注册公司吗?
Android自定义listview布局实现上拉加载下拉刷新功能
Laravel如何自定义错误页面(404, 500)?(代码示例)
浅谈javascript alert和confirm的美化
laravel怎么为应用开启和关闭维护模式_laravel应用维护模式开启与关闭方法
如何在 Python 中将列表项按字母顺序编号(a.、b.、c. …)
如何在Windows虚拟主机上快速搭建网站?
Laravel如何生成API文档?(Swagger/OpenAPI教程)
Laravel如何将应用部署到生产服务器_Laravel生产环境部署流程
如何在服务器上配置二级域名建站?
如何在阿里云虚拟机上搭建网站?步骤解析与避坑指南
如何自定义建站之星网站的导航菜单样式?
香港服务器租用费用高吗?如何避免常见误区?
Laravel怎么使用Collection集合方法_Laravel数组操作高级函数pluck与map【手册】
DeepSeek是免费使用的吗 DeepSeek收费模式与Pro版本功能详解
北京企业网站设计制作公司,北京铁路集团官方网站?
Linux系统命令中tree命令详解
活动邀请函制作网站有哪些,活动邀请函文案?
node.js报错:Cannot find module 'ejs'的解决办法
大连网站制作公司哪家好一点,大连买房网站哪个好?
制作ppt免费网站有哪些,有哪些比较好的ppt模板下载网站?
laravel怎么为API路由添加签名中间件保护_laravel API路由签名中间件保护方法
Laravel如何处理和验证JSON类型的数据库字段
Laravel怎么实现搜索高亮功能_Laravel结合Scout与Algolia全文检索【实战】
制作电商网页,电商供应链怎么做?
Midjourney怎样加参数调细节_Midjourney参数调整技巧【指南】
如何利用DOS批处理实现定时关机操作详解
javascript基本数据类型及类型检测常用方法小结
uc浏览器二维码扫描入口_uc浏览器扫码功能使用地址
Laravel Session怎么存储_Laravel Session驱动配置详解
轻松掌握MySQL函数中的last_insert_id()
Laravel怎么解决跨域问题_Laravel配置CORS跨域访问
Win11怎么查看显卡温度 Win11任务管理器查看GPU温度【技巧】
laravel服务容器和依赖注入怎么理解_laravel服务容器与依赖注入解析
大学网站设计制作软件有哪些,如何将网站制作成自己app?
如何批量查询域名的建站时间记录?
Laravel如何创建自定义Artisan命令?(代码示例)
Laravel如何创建和注册中间件_Laravel中间件编写与应用流程
通义万相免费版怎么用_通义万相免费版使用方法详细指南【教程】
如何在橙子建站上传落地页?操作指南详解
Python函数文档自动校验_规范解析【教程】
黑客如何通过漏洞一步步攻陷网站服务器?
HTML5空格和nbsp有啥关系_nbsp的作用及使用场景【说明】
如何快速查询域名建站关键信息?
Laravel如何配置.env文件管理环境变量_Laravel环境变量使用与安全管理
Win11摄像头无法使用怎么办_Win11相机隐私权限开启教程【详解】


