终极指南:Windows安卓驱动一键安装工具,告别黄色感叹号!
2026/6/16 6:03:51
在Java中把一个文件夹下的所有文件复制到另一个文件夹(支持多级目录、空文件夹、文件覆盖等场景),以下是基于Java原生API的完整实现方案(兼容Java 8+,无需额外依赖):
importjava.io.File;importjava.io.FileInputStream;importjava.io.FileOutputStream;importjava.io.IOException;importjava.nio.channels.FileChannel;/** * 文件夹复制工具类(支持多级目录、文件覆盖) */publicclassFolderCopyUtil{/** * 核心方法:复制源文件夹下的所有文件/目录到目标文件夹 * @param sourceDirPath 源文件夹路径(如:D:/source) * @param targetDirPath 目标文件夹路径(如:D:/target) * @throws IOException IO异常(文件无法读取/写入) */publicstaticvoidcopyFolder(StringsourceDirPath,StringtargetDirPath)throwsIOException{FilesourceDir=newFile(sourceDirPath);FiletargetDir=newFile(targetDirPath);// 步骤1:校验源文件夹合法性if(!sourceDir.exists()){thrownewIOException("源文件夹不存在:"+sourceDirPath);}if(!sourceDir.isDirectory()){thrownewIOException("路径不是合法文件夹:"+sourceDirPath);}// 步骤2:创建目标文件夹(递归创建多级目录,已存在则无影响)if(!targetDir.exists()){booleanisCreated=targetDir.mkdirs();if(!isCreated){thrownewIOException("目标文件夹创建失败:"+targetDirPath);}}// 步骤3:遍历源文件夹下的所有文件/子目录File[]files=sourceDir.listFiles();if(files==null){// 源文件夹为空或无读取权限return;}for(Filefile:files){StringtargetFilePath=targetDirPath+File.separator+file.getName();if(file.isFile()){// 步骤4:复制文件(覆盖已存在的目标文件)copyFile(file,newFile(targetFilePath));System.out.println("文件复制成功:"+file.getPath()+" → "+targetFilePath);}elseif(file.isDirectory()){// 步骤5:递归复制子目录copyFolder(file.getPath(),targetFilePath);System.out.println("目录复制成功:"+file.getPath()+" → "+targetFilePath);}}}/** * 辅助方法:复制单个文件(使用NIO FileChannel,效率更高) * @param sourceFile 源文件 * @param targetFile 目标文件 * @throws IOException IO异常 */privatestaticvoidcopyFile(FilesourceFile,FiletargetFile)throwsIOException{// 覆盖目标文件(若已存在则删除后重建)if(targetFile.exists()){booleanisDeleted=targetFile.delete();if(!isDeleted){thrownewIOException("目标文件覆盖失败,无法删除已有文件:"+targetFile.getPath());}}// 使用NIO通道复制(比传统字节流效率更高)try(FileInputStreamfis=newFileInputStream(sourceFile);FileOutputStreamfos=newFileOutputStream(targetFile);FileChannelinChannel=fis.getChannel();FileChanneloutChannel=fos.getChannel()){// 批量传输字节,避免逐字节复制,提升大文件复制效率longtransferred=0;longfileSize=inChannel.size();while(transferred<fileSize){transferred+=inChannel.transferTo(transferred,fileSize-transferred,outChannel);}}}// 测试方法publicstaticvoidmain(String[]args){// 替换为你的源文件夹和目标文件夹路径StringsourceDir="D:/test/source";StringtargetDir="D:/test/target";try{copyFolder(sourceDir,targetDir);System.out.println("文件夹复制完成!");}catch(IOExceptione){System.err.println("文件夹复制失败:"+e.getMessage());e.printStackTrace();}}}核心API解析
File.mkdirs():递归创建多级目录(如目标路径是D:/a/b/c,若a/b不存在,会自动创建),区别于mkdir()(仅创建单级目录);FileChannel.transferTo():NIO通道复制文件,直接利用操作系统底层IO,比传统InputStream/OutputStream逐字节复制效率高,尤其适合大文件;try-with-resources:自动关闭流/通道,避免手动关闭遗漏导致的资源泄露。关键特性适配
copyFile方法中增加判断:if(targetFile.exists()){System.out.println("目标文件已存在,跳过复制:"+targetFile.getPath());return;}listFiles()返回null,直接返回不报错;目标空文件夹会正常创建;copyFolder,支持复制源文件夹下的所有子目录及文件;IOException并提示具体原因。路径兼容性
File.separator代替硬编码的/或\,兼容Windows(\)和Linux/Mac(/)系统;D:/test)和相对路径(如./source)。若使用Java 7及以上版本,可借助java.nio.file.Files工具类简化代码,无需手动实现文件复制逻辑:
importjava.io.IOException;importjava.nio.file.*;publicclassFolderCopyWithFilesUtil{publicstaticvoidcopyFolder(StringsourceDirPath,StringtargetDirPath)throwsIOException{PathsourcePath=Paths.get(sourceDirPath);PathtargetPath=Paths.get(targetDirPath);// 递归复制目录,配置复制选项(覆盖已存在文件)Files.walkFileTree(sourcePath,newSimpleFileVisitor<Path>(){@OverridepublicFileVisitResultpreVisitDirectory(Pathdir,BasicFileAttributesattrs)throwsIOException{// 创建目标目录(递归)PathtargetDir=targetPath.resolve(sourcePath.relativize(dir));if(!Files.exists(targetDir)){Files.createDirectories(targetDir);}returnFileVisitResult.CONTINUE;}@OverridepublicFileVisitResultvisitFile(Pathfile,BasicFileAttributesattrs)throwsIOException{// 复制文件(覆盖已存在)PathtargetFile=targetPath.resolve(sourcePath.relativize(file));Files.copy(file,targetFile,StandardCopyOption.REPLACE_EXISTING);System.out.println("复制文件:"+file+" → "+targetFile);returnFileVisitResult.CONTINUE;}});}publicstaticvoidmain(String[]args){StringsourceDir="D:/test/source";StringtargetDir="D:/test/target";try{copyFolder(sourceDir,targetDir);System.out.println("复制完成!");}catch(IOExceptione){e.printStackTrace();}}}File+FileChannel实现,兼容性好,适合理解底层逻辑;Files.walkFileTree(Java 7+),代码更简洁,无需手动处理递归和文件复制;