Java的copy文件和文件夹以及删除文件夹(包括递归与非递归算法)

本文介绍了一种用于复制文件及目录的算法实现,包括递归与非递归两种方式,并提供了删除目录的算法。此外,还展示了如何读取目录中的文件。
 

Copy文件算法

 /**
     * <pre>
     * 复制文件
     * 源文件不存在,直接返回
     * 目标文件不存在时,创建父目录
     * </pre>
     *
     * @param srcFile 源文件
     * @param destFile 目标文件
     */
    public static void copy(File srcFile, File destFile) {
        //源文件不存在,直接返回
        if (!srcFile.exists()) {
            logger.info("源文件["+ srcFile.getName() +"]不存在");
            return;
        }
        //目标文件不存在时,创建父目录
        if (!destFile.exists()) {
            logger.info("目标文件["+ destFile.getName() +"]所在的父目录不存在,创建父目录");
            destFile.getParentFile().mkdirs();
        }
        FileInputStream fis = null;
        BufferedInputStream bis = null;
        FileOutputStream fos = null;
        BufferedOutputStream bos = null;
        try {
            fis = new FileInputStream(srcFile);
            bis = new BufferedInputStream(fis);
            fos = new FileOutputStream(destFile);
            bos = new BufferedOutputStream(fos);
            byte[] buffer = new byte[1024 * 5];

            int length;
            while ((length = bis.read(buffer)) != -1) {
                bos.write(buffer, 0, length);
            }
            bos.flush();

        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        } finally {
            try {
                if (fis != null) {
                    fis.close();
                }
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
            }
            try {
                if (fos != null) {
                    fos.close();
                }
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
            }
            try {
                if (bis != null) {
                    bis.close();
                }
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
            }
            try {
                if (bos != null) {
                    bos.close();
                }
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
            }
        }
    }


 

Copy目录(递归算法)

/**
	 * 复制目录下的所有到另一目录
	 * @param srcDir
	 * @param destDir
	 */
	public static void copyDir(File srcDir,File destDir){
		//生成目录
		if(!destDir.exists()){
			destDir.mkdirs();
		}
		//循环源目录
		File[]srcFiles = srcDir.listFiles();
		for (int i = 0; i < srcFiles.length; i++) {
			File src = srcFiles[i];
			if(src.isFile()){
				File targetFile = new File(destDir.getAbsolutePath() + "\\" + src.getName());
				copy(src, targetFile);
			}else{
				copyDir(new File(srcDir + "\\" + src.getName()), new File(destDir + "\\" + src.getName()));
			}
		}
	}

 

Copy目录(非递归算法):

 /**
     * 拷贝目录(非递归)
     * @param srcDir 源目录
     * @param destDir 目标目录
     */
    public static void copyDirNonRecursion(File srcDir, File destDir) {
        //生成目录
        if (!destDir.exists()) {
            logger.info("目标文件["+ destDir.getName() +"]的目录不存在,创建相应目录");
            destDir.mkdirs();
        }

        Stack<File> fileStack = new Stack<File>();
        fileStack.push(srcDir);
        File curFile;
        File preFile = null;
        String parentPath = destDir.getAbsolutePath();
        parentPath = parentPath.replaceAll("[\\\\]", "/");
        String srcPath = srcDir.getAbsolutePath();
        while (!fileStack.empty()) {
            curFile = fileStack.peek();
            File[] fileLists = curFile.listFiles();
            //当前文件为非目录,或者空目录或者前一个文件的父目录为当前文件时
            if (curFile.isFile()
                    || (preFile != null && (preFile.getParent().equals(curFile.getAbsolutePath())))
                    || (fileLists.length == 0)) {
                File popFile = fileStack.pop();
                String filePath = popFile.getAbsolutePath();
                if (filePath.equals(srcPath)) {
                    continue;
                }
                filePath = filePath.replaceAll("[\\\\]", "/");
                filePath = filePath.substring(srcPath.length() + 1);
                filePath = parentPath + "/" + filePath;
                if (popFile.isFile()) {
                    copy(popFile, new File(filePath));
                } else {
                    File dir = new File(filePath);
                    dir.mkdirs();
                }
                preFile = curFile;
            } else {
                for (File file : fileLists) {
                    fileStack.push(file);
                }
            }
        }
    }


 


删除目录(递归算法)

/**
	 * 给入一个目录,删除该目录下的所有文件。
	 * @param dir
	 */
	public static void deleteDir(File dir){
		if(dir.isDirectory()){
			File[] listFiles = dir.listFiles();
			for (int i = 0; i < listFiles.length; i++) {
				File f = listFiles[i];
				if(f.isFile()){
					f.delete();
				} else if(f.isDirectory()){
					deleteDir(f);
				}
			}
			//删除当前目录
			dir.delete();
		}
	}


 

 删除目录(非递归算法):

    /**
     * 删除目录(非递归)
     * @param srcDir 源目录
     */
    public static void deleteDirNonRecursion(File srcDir) {
        Stack<File> fileStack = new Stack<File>();
        fileStack.push(srcDir);
        File curFile;
        File preFile = null;
        while (!fileStack.empty()) {
            curFile = fileStack.peek();
            File[] fileLists = curFile.listFiles();
            //当前文件为非目录,或者空目录或者前一个文件的父目录为当前文件时
            if (curFile.isFile()
                    || (preFile != null && (preFile.getParent().equals(curFile.getAbsolutePath())))
                    || (fileLists.length == 0)) {
                File popFile = fileStack.pop();
                popFile.delete();
                preFile = curFile;
            } else {
                for (File file : fileLists) {
                    fileStack.push(file);
                }
            }
        }
    }


 

读取目录(非递归算法):

public void readFile(File rootFile) {
        Stack<File> fileStack = new Stack<File>();
        fileStack.push(rootFile);
        File curFile;
        File preFile = null;
        while (!fileStack.empty()) {
            curFile = fileStack.peek();
            File[] fileLists = curFile.listFiles();
            if (curFile.isFile()
                    || (preFile != null && (preFile.getParent().equals(curFile.getAbsolutePath())))
                    || (fileLists.length == 0)) {
                System.err.println(curFile.getAbsolutePath());
                fileStack.pop();
                preFile = curFile;
            } else {
                for (File file : fileLists) {
                    fileStack.push(file);
                }
            }
        }
    }


 

以下是符合技术文档规范的精准翻译,兼顾术语一致性与可读性: ### 第一阶段(Первая фаза) #### 任务说明(Задание) 现有一个包含大量大文件文件夹,用户已整理了部分文件但未删除文件。目前用户无法区分哪些文件已整理到其他文件夹,哪些仍未整理。需开发一款应用程序,帮助用户识别未整理的文件文件判定规则:若文件存在于原始文件夹中,但在所有目标文件夹中均不存在,则视为未整理文件。 --- ### 使用场景(Варианты использования) #### 用户操作(Пользователь) ##### 文件夹与路径管理(Управление папками и путями) - 指定已整理文件文件夹路径 - 指定未整理文件文件夹路径 - 清除已选文件夹历史记录 - 将上一个“未整理文件文件夹作为新分析的数据源 ##### 操作执行(Запуск операций) - 生成所有已整理文件的列表 - 生成所有未整理文件的列表 - 查找未整理文件 - 将找到的未整理文件放入“未整理文件-日期-时间”文件夹保留原始文件夹结构 ##### 结果管理(Работа с результатами) - 以表格形式查看未整理文件列表 - 按文件名、日期、类型、大小对列表进行排序 - 显示未整理文件的数量 ##### 忽略列表管理(Управление игнор-листом) - 将文件添加到忽略列表(自动创建“忽略列表”文件夹) - 查看忽略列表中的文件 - 从忽略列表中恢复文件 --- ### 功能需求(Функциональные требования) #### 文件夹选择与管理 - 用户可指定已整理文件的根文件夹(程序将递归检查所有子文件夹,确认是否包含原始文件夹中的文件) - 用户可指定未整理文件的根文件夹(若根文件夹中包含子文件夹,程序将递归查找这些子文件夹中的文件是否已整理) - 程序应提供上一个创建的“未整理文件-日期-时间”文件夹,作为未整理数据的根文件夹选项 #### 信息显示 - 应用界面需以以下格式展示未整理文件文件名、修改日期、文件类型、大小 - 应用界面需支持按文件名、日期、类型、大小对文件进行排序 #### 忽略列表管理 - 查找未整理文件算法执行完成后,用户可在界面中将无需检查的文件添加到忽略列表 - 所有忽略列表中的文件均存入“忽略列表”文件夹(该文件夹与未整理文件的根文件夹位于同一目录) - 后续查找时,这些文件将被自动忽略,不纳入“未整理文件-日期-时间”文件夹 #### 文件扫描 - 程序需递归读取未整理文件文件夹中的所有文件生成包含完整文件路径的列表 - 程序需递归读取已整理文件文件夹中的所有文件生成包含完整文件路径的列表 #### 结果生成 - 程序执行完成后,需创建名为“未整理文件 日期-时间”的文件夹,存储未整理数据 - 若未整理文件的根文件夹中存在非空的子文件夹,需保留其子文件夹名称及内部文件(排除已整理文件) - “未整理文件-日期-时间”文件夹需创建在用户指定的未整理文件文件夹所在目录 #### 会话保存 - 程序需保存上一次选择的已整理数据根文件夹路径 - 程序需保存所有已创建的“未整理文件文件夹历史记录,供后续使用 #### 忽略列表保存 - 程序需在多次运行会话之间保留忽略列表状态 - 后续文件分析时,程序需自动应用忽略列表规则 #### 未整理文件判定逻辑 - 判定规则:文件存在于原始文件夹,但在所有目标文件夹中均不存在,则视为未整理 - 文件对比时需纳入忽略列表中的文件(即忽略列表文件不参与未整理判定) - 算法递归处理嵌套文件夹结构 #### 目录结构处理 - 生成结果文件夹时,需保留原始子文件夹结构 - 文件的相对路径需以未整理文件文件夹为基准进行保留 --- ### 非功能需求(Нефункциональные требования) - 应用需能高效处理大容量数据 - 应用需能高效处理大尺寸文件 - 应用需能稳定处理权限受限的文件 - 运行过程中产生的错误需记录日志,但不得中断程序执行 - 界面需简洁直观,便于用户操作 - 支持系统:Linux、Windows 10及以上版本 --- 根据此阶段内容,写出所需所有代码
最新发布
11-09
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

psyuhen

你的鼓励是我最大的动力谢谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值