如何正确移动文件以避免 NoSuchFileException 错误
发布时间 - 2026-02-02 00:00:00 点击率:次本文详解因循环中重复调用 files.move() 导致文件被多次移动、触发 nosuchfileexception 的根本原因,并提供结构清晰、资源安全的修复方案,确保每个 csv 文件仅被移动一次到对应目标目录。
在您提供的 Quartz 定时任务代码中,核心问题并非路径错误或权限缺失,而是逻辑控制缺陷:for (CsvLine item : beans) 循环内未及时退出,导致同一文件在满足条件后被多次尝试移动 —— 第二次移动时源文件已不存在,从而抛出 java.nio.file.NoSuchFileException。
? 问题定位:重复移动是罪魁祸首
原始代码中:
if(item.getValue().equals(2) || ...) {
Path copied = Paths.get(file.getParent() + "/invalid_files");
Files.move(originalPath, copied.resolve(...)); // ✅ 第一次成功移动
}
// ❌ 缺少 break;循环继续 → 下一轮 item 再次触发 move → 源文件已不存在!由于未使用 break 中断循环,只要 beans 列表中存在多个匹配项(或后续迭代),就会对同一个 originalPath 多次执行 Files.move()。而 Files.move() 是原子性操作:首次成功后源文件即被移走,第二次必然失败。
此外,代码中还存在 资源管理隐患:手动调用 br.close() 并置于 try-with-resources 块内部,违反了自动资源管理原则,易引发 IllegalStateException 或掩盖真实异常。
✅ 推荐修复方案:单次决策 + 统一移动
以下是重构后的健壮实现,遵循“先判断归类、再统一移动”原则,逻辑清晰且线程安全:
@Override
public void execute(JobExecutionContext context) {
File directoryPath = new File("C:\\csv\\nov");
// 创建目标子目录(processed / invalid_files)
try {
Path processedDir = Path.of(directoryPath.getAbsolutePath(), "processed");
Path invalidDir = Path.of(directoryPath.getAbsolutePath(), "invalid_files");
Files.createDirectories(processedDir); // createDirectories 安全创建多级目录
Files.createDirectories(invalidDir);
} catch (IOException e) {
throw new RuntimeException("Failed to create directories", e);
}
// 过滤 CSV 文件
FilenameFilter csvFilter = (dir, name) -> name.toLowerCase().en
dsWith(".csv");
File[] csvFiles = directoryPath.listFiles(csvFilter);
if (csvFiles == null) {
System.out.println("No CSV files found in directory.");
return;
}
for (File file : csvFiles) {
Path originalPath = file.toPath();
Path targetPath = Path.of(file.getParent(), "processed", file.getName()); // 默认移至 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))) {
targetPath = Path.of(file.getParent(), "invalid_files", file.getName());
System.out.printf("⚠️ Invalid value %d found in %s → will move to invalid_files%n",
value, file.getName());
break; // ✅ 关键:立即终止检测,避免重复 move
}
}
} catch (Exception e) {
// 解析失败视为异常文件,归入 invalid_files
targetPath = Path.of(file.getParent(), "invalid_files", file.getName());
System.err.printf("❌ Parsing failed for %s: %s → moved to invalid_files%n",
file.getName(), e.getMessage());
}
// ✅ 统一执行移动(无论 valid/invalid/parse-error)
try {
Files.move(originalPath, targetPath, StandardCopyOption.REPLACE_EXISTING);
System.out.printf("✅ Moved %s → %s%n", file.getName(), targetPath.getParent().getFileName());
} catch (IOException e) {
throw new RuntimeException("Failed to move file: " + file.getName(), e);
}
}
} ⚠️ 关键改进说明
- 单次判定,统一移动:将移动逻辑完全移出数据解析循环,在 try-with-resources 外统一执行,彻底杜绝重复移动。
- break 确保早停:一旦确认文件为 invalid,立即 break,不进行冗余遍历。
- 异常文件兜底处理:catch (Exception) 中将解析失败的文件也归入 invalid_files,提升鲁棒性。
- createDirectories() 替代 createDirectory():自动创建父目录(如 invalid_files 不存在时),避免 NoSuchFileException 在目录创建阶段发生。
- 日志分级输出:使用 System.out.printf 和 System.err.printf 区分正常流程与错误信息,便于运维排查。
? 补充建议
- 若 CSV 文件极大,可考虑使用 Files.lines() 流式读取前几行做快速校验,避免全量解析。
- 生产环境建议集成 SLF4J 日志框架替代 System.out,并添加 MDC 追踪 Job 执行上下文。
- 对于高并发场景,可在 move 前加 Files.exists(originalPath) 双重检查(虽非必需,但可增强防御性)。
通过以上重构,您的任务将稳定运行,不再因逻辑漏洞触发 NoSuchFileException,同时代码可读性、可维护性与健壮性均显著提升。
# java
# csv
# ai
# 代码可读性
# nio
# for
# try
# catch
# printf
# break
# 循环
# 线程
# 并发
# 重构
# 不存在
# 遍历
# 资源管理
# 您的
# 环中
# 首次
# 多个
# 可在
# 会对
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
Linux后台任务运行方法_nohup与&使用技巧【技巧】
Laravel如何使用Eloquent进行子查询
如何用低价快速搭建高质量网站?
昵图网官网入口 昵图网素材平台官方入口
悟空识字如何进行跟读录音_悟空识字开启麦克风权限与录音
,南京靠谱的征婚网站?
Win10如何卸载预装Edge扩展_Win10卸载Edge扩展教程【方法】
Laravel如何构建RESTful API_Laravel标准化API接口开发指南
个人摄影网站制作流程,摄影爱好者都去什么网站?
JavaScript中的标签模板是什么_它如何扩展字符串功能
php json中文编码为null的解决办法
Laravel路由Route怎么设置_Laravel基础路由定义与参数传递规则【详解】
JS实现鼠标移上去显示图片或微信二维码
夸克浏览器网页跳转延迟怎么办 夸克浏览器跳转优化
香港服务器网站推广:SEO优化与外贸独立站搭建策略
Laravel如何实现登录错误次数限制_Laravel自带LoginThrottles限流配置【方法】
矢量图网站制作软件,用千图网的一张矢量图做公司app首页,该网站并未说明版权等问题,这样做算不算侵权?应该如何解决?
Python图片处理进阶教程_Pillow滤镜与图像增强
邀请函制作网站有哪些,有没有做年会邀请函的网站啊?在线制作,模板很多的那种?
Laravel如何设置定时任务(Cron Job)_Laravel调度器与任务计划配置
Laravel如何使用Passport实现OAuth2?(完整配置步骤)
想要更高端的建设网站,这些原则一定要坚持!
HTML透明颜色代码在Angular里怎么设置_Angular透明颜色使用指南【详解】
Laravel如何实现全文搜索_Laravel Scout集成Algolia或Meilisearch教程
Laravel如何使用Telescope进行调试?(安装和使用教程)
jQuery中的100个技巧汇总
Laravel怎么解决跨域问题_Laravel配置CORS跨域访问
详解Huffman编码算法之Java实现
Laravel Eloquent性能优化技巧_Laravel N+1查询问题解决
Android 常见的图片加载框架详细介绍
Laravel如何使用Facades(门面)及其工作原理_Laravel门面模式与底层机制
Laravel如何操作JSON类型的数据库字段?(Eloquent示例)
WEB开发之注册页面验证码倒计时代码的实现
javascript中的try catch异常捕获机制用法分析
Laravel表单请求验证类怎么用_Laravel Form Request分离验证逻辑教程
简历在线制作网站免费版,如何创建个人简历?
如何在万网ECS上快速搭建专属网站?
Laravel模型关联查询教程_Laravel Eloquent一对多关联写法
Laravel怎么生成URL_Laravel路由命名与URL生成函数详解
公司门户网站制作流程,华为官网怎么做?
Microsoft Edge如何解决网页加载问题 Edge浏览器加载问题修复
香港服务器租用费用高吗?如何避免常见误区?
怎么用AI帮你为初创公司进行市场定位分析?
Angular 表单中正确绑定输入值以确保提交与验证正常工作
如何在IIS7上新建站点并设置安全权限?
iOS UIView常见属性方法小结
Python面向对象测试方法_mock解析【教程】
如何自定义建站之星网站的导航菜单样式?
ChatGPT回答中断怎么办 引导AI继续输出完整内容的方法
免费制作统计图的网站有哪些,如何看待现如今年轻人买房难的情况?


