{"record":{"id":"2248b3c9a7fd6dc4","repo":"chinabugotech/hutool","slug":"src-is-a-directory-but-dest-is-a-file","errorCode":null,"errorMessage":"Src is a directory but dest is a file!","messagePattern":"Src is a directory but dest is a file!","errorType":"exception","errorClass":"IORuntimeException","httpStatus":null,"severity":"error","filePath":"hutool-core/src/main/java/cn/hutool/core/io/file/FileCopier.java","lineNumber":185,"sourceCode":"\t */\n\t@Override\n\tpublic File copy() throws IORuntimeException{\n\t\tfinal File src = this.src;\n\t\tFile dest = this.dest;\n\t\t// check\n\t\tAssert.notNull(src, \"Source File is null !\");\n\t\tif (false == src.exists()) {\n\t\t\tthrow new IORuntimeException(\"File not exist: \" + src);\n\t\t}\n\t\tAssert.notNull(dest, \"Destination File or directiory is null !\");\n\t\tif (FileUtil.equals(src, dest)) {\n\t\t\tthrow new IORuntimeException(\"Files '{}' and '{}' are equal\", src, dest);\n\t\t}\n\n\t\tif (src.isDirectory()) {// 复制目录\n\t\t\tif(dest.exists() && false == dest.isDirectory()) {\n\t\t\t\t//源为目录，目标为文件，抛出IO异常\n\t\t\t\tthrow new IORuntimeException(\"Src is a directory but dest is a file!\");\n\t\t\t}\n\t\t\tif(FileUtil.isSub(src, dest)) {\n\t\t\t\tthrow new IORuntimeException(\"Dest is a sub directory of src !\");\n\t\t\t}\n\n\t\t\tfinal File subTarget = isCopyContentIfDir ? dest : FileUtil.mkdir(FileUtil.file(dest, src.getName()));\n\t\t\tinternalCopyDirContent(src, subTarget);\n\t\t} else {// 复制文件\n\t\t\tdest = internalCopyFile(src, dest);\n\t\t}\n\t\treturn dest;\n\t}\n\n\t//----------------------------------------------------------------------------------------- Private method start\n\t/**\n\t * 拷贝目录内容，只用于内部，不做任何安全检查<br>\n\t * 拷贝内容的意思为源目录下的所有文件和目录拷贝到另一个目录下，而不拷贝源目录本身\n\t *","sourceCodeStart":167,"sourceCodeEnd":203,"githubUrl":"https://github.com/chinabugotech/hutool/blob/8870454b2a0c29cc6ffd31dcf5667c8ceb2fc442/hutool-core/src/main/java/cn/hutool/core/io/file/FileCopier.java#L167-L203","documentation":"When src is a directory, FileCopier.copy() requires dest to be a directory as well (or non-existent so it can be created). If dest already exists and is a regular file, the copy is a type mismatch and it throws IORuntimeException(\"Src is a directory but dest is a file!\").","triggerScenarios":"Calling copy() on a FileCopier where src is a directory and dest is an existing regular file.","commonSituations":"Copying a folder into a location already occupied by a file; dest path points at an existing file; configuration mistake where src is a directory but dest is a file path.","solutions":["Delete or rename the existing dest file before copying a directory onto it.","Choose a dest that is a directory or does not exist yet.","Check dest type before copy() and route directories vs files differently."],"exampleFix":"// before\nFileCopier.create(srcDir, existingFile).copy(); // throws: type mismatch\n\n// after\nif (dest.exists() && dest.isFile()) {\n    FileUtil.del(dest); // or rename\n}\nFileCopier.create(srcDir, dest).copy();","handlingStrategy":"validation","validationCode":"if (src.isDirectory() && dest.exists() && dest.isFile()) {\n    FileUtil.del(dest); // or rename aside\n}\nreturn FileCopier.create(src, dest).copy();","typeGuard":"static boolean compatibleCopyTargets(File src, File dest) {\n    if (src == null || dest == null) return false;\n    if (src.isDirectory() && dest.exists() && dest.isFile()) return false;\n    return true;\n}","tryCatchPattern":"try {\n    return FileCopier.create(src, dest).copy();\n} catch (IORuntimeException e) {\n    if (e.getMessage().contains(\"Src is a directory but dest is a file\")) {\n        FileUtil.del(dest);\n        return FileCopier.create(src, dest).copy();\n    }\n    throw e;\n}","preventionTips":["Check dest type before copying a directory onto it.","Remove or rename a conflicting dest file first.","Route directory vs file copies through separate logic."],"tags":["io","file","copy","type-mismatch"],"backgroundTag":null,"analyzedSha":"8870454b2a0c29cc6ffd31dcf5667c8ceb2fc442","analyzedAt":"2026-08-14T04:01:12.892Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}