org.apache.commons.io.FileUtils.copyFileToDirectory复制文件失败求助
解决FileUtils.copyFileToDirectory抛出java.io.IOException: Bad pathname异常
问题背景
使用org.apache.commons.io.FileUtils.copyFileToDirectory(sourceFile, destDir)实现跨路径文件复制时,在Windows 10专业工作站版上抛出Bad pathname异常,但相同JDK11环境与代码在其他机器可正常运行。已完成以下排查:
- JDK11安装正常
- 原生FileInputStream/FileOutputStream、命令行copy命令可正常复制文件
- 当前用户拥有管理员权限,目标目录具备读写权限
- 源文件与目标目录的绝对路径、规范路径均存在,且路径长度小于256字符
复制代码
private void copyFile() { try { String data = "C:\\Test_data\\My_Folder\\data"; String destination = "D:\\test\\CC"; File destDir = new File(destination); File source = new File(data); File files[] = source.listFiles(); for (File sourceFile : files) { if (sourceFile.getName().equals("testdata.yaml")) { if (destDir != null) { FileUtils.copyFileToDirectory(sourceFile, destDir); System.out.println("File copied"); } } } } catch (IOException e) { System.out.println("Error while copying file.......!!!!! "); e.printStackTrace(); } }
异常栈
Error while copying file.......!!!!! java.io.IOException: Bad pathname at java.base/java.io.WinNTFileSystem.canonicalize0(Native Method) at java.base/java.io.WinNTFileSystem.canonicalize(WinNTFileSystem.java:483) at java.base/java.io.File.getCanonicalPath(File.java:626) at org.apache.commons.io.FileUtils.requireCanonicalPathsNotEquals(FileUtils.java:2601) at org.apache.commons.io.FileUtils.copyFile(FileUtils.java:842) at org.apache.commons.io.FileUtils.copyFile(FileUtils.java:783) at org.apache.commons.io.FileUtils.copyFileToDirectory(FileUtils.java:926) at org.apache.commons.io.FileUtils.copyFileToDirectory(FileUtils.java:897) at com.fileop.reader.App.addDatamapYamlToProjectLocation(App.java:29) at com.fileop.reader.App.main(App.java:16) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:61)
解决步骤
1. 升级Apache Commons IO版本
旧版本Commons IO可能存在与JDK11或Windows 10工作站版的路径处理兼容性bug,建议升级到2.15.0及以上的稳定版本。
2. 手动规范化路径后再操作
异常触发于系统级路径规范化步骤,可提前显式获取规范路径对应的File对象,避免后续调用出错:
private void copyFile() { try { String data = "C:\\Test_data\\My_Folder\\data"; String destination = "D:\\test\\CC"; // 显式获取规范路径 File destDir = new File(destination).getCanonicalFile(); File source = new File(data).getCanonicalFile(); File files[] = source.listFiles(); for (File sourceFile : files) { if (sourceFile.getName().equals("testdata.yaml")) { File canonicalSource = sourceFile.getCanonicalFile(); FileUtils.copyFileToDirectory(canonicalSource, destDir); System.out.println("File copied"); } } } catch (IOException e) { System.out.println("Error while copying file.......!!!!! "); e.printStackTrace(); } }
若getCanonicalFile()抛出异常,可直接定位路径中存在的问题(如隐藏不可见字符、非法字符)。
3. 检查路径中的特殊字符
确认路径/文件名中不存在:
- 全角空格、制表符等不可见控制字符
- Windows禁止的文件名字符(
/ \ : * ? " < > |)
即使路径实际存在,部分特殊字符在系统底层规范化时可能触发Bad pathname异常,可尝试重命名目录/文件后测试。
4. 验证系统短路径设置
Windows 10工作站版可能默认禁用8.3短路径支持,部分旧版库依赖短路径完成规范化。可通过以下命令启用:
fsutil behavior set disable8dot3 0
执行后重启系统,再测试复制操作。
5. 绕过规范路径检查(临时方案)
若以上方法无效,可直接使用FileUtils.copyFile重载方法,跳过源路径与目标路径的规范检查:
// 直接指定目标文件路径 File destFile = new File(destDir, sourceFile.getName()); FileUtils.copyFile(sourceFile, destFile, true); // true表示覆盖已存在文件
内容的提问来源于stack exchange,提问作者mayur patil
相关产品推荐
相关产品推荐

