标题


最新工作涉及到文件操作的内容,顺带花点时间把各种业务场景的方法都总结出来,供大家参考

对应Maven依赖、这块提醒千万别倒错包,这块的方法本人都亲测过,如果报错看下依赖是否正确

<dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.1</version>
        </dependency>
		<!-- 压缩用的的依赖 -->
        <dependency>
            <groupId>org.apache.ant</groupId>
            <artifactId>ant</artifactId>
            <version>1.10.5</version>
        </dependency>

使用方法前建议看方法的注释及代码,是否满足自己的实际需求,必要时调整一下即可

package cn.kgc.itrip.search.test;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;

import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;


/**
 * 文件操作工具类
 * todo 快速构建测试目录及文件:createMoreFiles
 * todo 检查篇
 * 判断路径是文件夹还是文件:isDirectoryOrFile(前提此路径已存在)
 * 查看文件是否存在:checkFileExist
 * 检查文件夹是否存在:checkDirectoryExist
 * 以上两种方法好像差别不太大,都能用来判断文件或者文件夹是否存在
 * 判断指定文件夹下是否含有任意文件:isHaveAnyFile(注意此方法忽略了文件夹)
 * 下面两个挺简单,没啥实用价值忽略掉
 * 检查指定文件夹下是否含有某类型文件(通过拿到文件的List,遍历是否存在指定类型即可)
 * 获取文件夹下所有的文件的数量
 * todo 查看篇
 * 获取目录下的文件(夹)getDirAllFile
 * 读取某个目录下所有文件、文件夹:getFilesAll
 * 返回一个目录(可包括子目录)下的所有文件:getFilesList(返回文件集合)
 * 返回一个目录(可包括子目录)下的所有目录名称:getDirList(返回文件夹集合)
 * 获取文件夹下的全部或指定文件格式的文件名称:getFileName
 * 检测某个目录下是否含有重名文件(夹):repetitionNum
 * todo 创建篇--------文件(夹)不存在则创建
 * 检查目录是否存在,不存在则创建目录,只会创建目录不会创建文件的呦:createDirectory、
 * createDirectory1(改进版),根据路径不同合理更换方法(路径是目录级别还是文件级别)
 * 检查目标路径文件是否存在,不存在则创建此目录及文件夹,会创建文件夹及文件:createDirectoryFile
 * 推荐使用半智能创建目录或是否创建出具体文件:createDirectoryOrFile
 * 判断文件是否存在如果存在就删除,不存在就新建:createNewFile
 * todo 复制篇幅-----
 * 复制文件 copyFile 、 copyFileToWriteFile 效果一致
 * 把文件复到一个文件夹:copyFileToDirectory
 * 把文件夹下所有内容复制到指定文件夹下:copyFilesCope
 * 复制文夹夹下的指定文件到目标文件夹:copyFileByName
 * 获取指定文件夹下的指定类型的文件,然后复制到指定的文件夹下:copyFileByType
 * 实现复制多个文件(夹)到指定目录下如果重名则重命名:copyFileOrDir
 * todo 删除篇
 * 判断文件是否存在如果存在就删除,不存在就新建:createNewFile
 * 清空指定文件夹下所有内容:delAllFile、removeDirectory(推荐)     不会删除此目录只是清空此目录下的所有内容
 * 删除指定文件夹及下所有内容:delFolder 、removeDirectoryAll(推荐)    会删除此文件夹及下面所有内容
 * 
 * 上面删除用到依赖包了,下面给出工作中用到的单个文件删除及

 * 删除指定路径下的单个文件:deleteFile
 * 删除指定路径下的多个文件:deleteFileList
 * 暴力删除,直接删除掉你指定的文件夹及目录下所有内容:deleteDirectoryAll
 * 删除指定文件夹下指定文件名:circleMethod
 * 删除指定文件夹下多个指定文件名:delMethod
 * 删除目标文件夹下指定文件格式的所有文件:circleMethodType
 * todo 重命名篇
 * 检查是否有重名 :duplicateName
 * 重名后的新的起名名称:getNewName
 * 指定文件夹重命名:reNameDirectory(必须在同一文件夹下)不友好,利用复制并命名
 * 指定文件重命名:reNameFile(必须在同一文件夹下),所以不采用,利用边复制边命名
 * 解读边复制边命名:文件的简单复制模块就有方法,文件的也简单,你直接复制原目录下的文件夹到另外一个新起好名称的文件夹下即可,就
 * 批量命名这块我给出两个代码示例,因为的根据你的具体业务规则来定,不好写活参
 * 批量修改文件名字:modifyFileNames (注换相反条件就会批量改文件夹名称)
 * 批量修改文件名字:recursiveTraversalFolder
 * 
 * todo 压缩、解压篇----这块内容情况较多写在下面的模块
 * 压缩指定文件到指定文件夹
 * 压缩指定目录到指定文件夹
 * 多个目录的文件压缩到一起到到指定文件夹
 * 多个文件或文件夹压缩的同一目录下:方法已在文章末尾提供
 * 
 * 常用方法篇
 * 获取文件名称前缀与后缀:getFileNameOrType
 * 返回路径中最后/出现的位置:getLastIndexOfGang
 * 获取上一级目录:getParentPath
 * 如果路径不以文件分隔符结尾,自动添加文件分隔符:getNeedPath
 * 实现动态根据文件夹路径或者文件路径,如果路径不存在则创建此文件,
 * 并是否创建出文件:createDirectoryOrFile
 * 修复路径,将 \\ 或 / 等替换为 File.separator:linuxPath
 * 上传文件重命名:rename、rename1、rename2
 */

public class FileUtil {

    /**
     * 快速构建测试目录及文件:createMoreFiles
     * createMoreFiles("C:\\Users\\test1\\test2\\")
     *
     * @throws IOException
     */
    private static void createMoreFiles(String path) throws IOException {
        Files.createDirectories(Paths.get(path));
        Files.write(Paths.get(path + "test2.log"), "helloTest2".getBytes());
        Files.write(Paths.get(path + "test3\\test3.log"), "helloTest3".getBytes());
    }

    /**
     * 判断路径是文件夹还是文件:isDirectoryOrFile
     * todo 前提此路径已存在
     * @param path
     * @return true 为文件夹  false为文件
     */
    public static boolean isDirectoryOrFile(String path) {
        File file = new File(path);
        if (file.isDirectory()) {
            return true;
        }
        if (file.isFile()) {
            return false;
        }
        return false;
    }

    /**
     * 查看文件是否存在:checkFileExist
     *
     * @param filePath 文件地址
     * @return true or false
     */
    public static boolean checkFileExist(String filePath) {
        File file = new File(filePath);
        return file.exists() ? true : false;
    }

    /**
     * 检查文件夹是否存在:checkDirectoryExist
     *
     * @param directoryPath
     * @return
     */
    public static boolean checkDirectoryExist(String directoryPath) {
        File file = new File(directoryPath);
        if (!file.exists() && !file.isDirectory()) {
            return false;
        }
        return true;
    }

    /**
     * 判断目录下是否含有文件:isHaveAnyFile
     * hasfile("C:\\Users\\雷神\\Desktop\\ribao\\h1h");
     * 读取某个文件夹下的所有文件来判断是否含有文件(不包括文件夹)
     */
    public static boolean isHaveAnyFile(String filepath) throws FileNotFoundException, IOException {
        File file = new File(filepath);
        if (!file.isDirectory()) {
            System.out.println("请输入一个目录");
            return false;
        } else if (file.isDirectory()) {
            String[] filelist = file.list();
            for (int i = 0; i < filelist.length; i++) {
                if (filelist[i].contains(".")) {
                    System.out.println("该目录下存在文件");
                    return true;
                }
            }
            System.out.println("该目录下不存在文件");
            return false;

        }
        return false;
    }

    /**
     * 获取文件夹下的全部或指定文件格式的文件名称:getFileName
     * getFileName("C:\\Users\\h1h", "txt")
     * 读取某个文件夹下的所有文件来判断是否含有文件
     *
     * @param filepath
     * @return
     * @throws FileNotFoundException
     * @throws IOException
     */
    public static List<String> getFileName(String filepath, String fileType) throws FileNotFoundException, IOException {
        String type = ".";
        if (!("".equals(fileType) || null == fileType)) {
            type = "." + fileType;
        }
        File file = new File(filepath);
        List<String> listFileName = new ArrayList();
        if (!file.isDirectory()) {
            System.out.println("请输入一个目录");
        } else if (file.isDirectory()) {
            String[] filelist = file.list();
            for (int i = 0; i < filelist.length; i++) {
                if (filelist[i].contains(type)) {
                    listFileName.add(filelist[i]);
                }
            }
        }
        return listFileName;
    }

/**
     * 读取某个目录下所有文件、文件夹:getFilesAll
     *
     * @param path
     * @return
     */
    public static ArrayList<File> getFilesAll(String path) {
        ArrayList<File> files = new ArrayList<File>();
        File file = new File(path);
        File[] tempList = file.listFiles();
        for (int i = 0; i < tempList.length; i++) {
            if (tempList[i].isFile()) {
                files.add(tempList[i]);
            }
            if (tempList[i].isDirectory()) {
                ArrayList<File> files1 = getFilesAll(tempList[i].getPath());
                files.addAll(files1);
            }
        }
        return files;
    }


    /**
     * 返回一个目录(可包括子目录)下的所有文件:getFilesList(返回文件集合)
     * 读取某个目录下(包括子文件夹下)所有文件、文件夹
     * @param path        文件夹路径
     * @param childFolder 是否遍历子文件夹下的文件
     * @return 返回一个文件集合,进而可获取文件绝对路径、文件名等
     */
    public static ArrayList<File> getFilesList(String path, boolean childFolder) {
        ArrayList<File> files = new ArrayList<File>();
        File file = new File(path);
        File[] tempList = file.listFiles();
        for (int i = 0; i < tempList.length; i++) {
            if (tempList[i].isFile()) {
                files.add(tempList[i]);
            }
            //递归遍历出子文件下的文件,不需要的可以把childFolder设置为 false
            if (tempList[i].isDirectory() && childFolder) {
                ArrayList<File> files1 = getFilesList(tempList[i].getPath(), childFolder);
                files.addAll(files1);
            }
        }
        return files;
    }

    /**
     * 返回一个目录(可包括子目录)下的所有目录名称:getDirList(返回文件夹集合)
     * 读取某个目录下(包括子目录下)所有文目录名称
     * @param path        文件夹路径
     * @param childFolder 是否遍历子文件夹
     * @return 返回一个文件目录集合,进而可获取目录绝对路径、文件名等
     */
    public static ArrayList<File> getDirList(String path, boolean childFolder) {
        ArrayList<File> files = new ArrayList<File>();
        File file = new File(path);
        File[] tempList = file.listFiles();
        for (int i = 0; i < tempList.length; i++) {
            if (tempList[i].isDirectory()) {
                files.add(tempList[i]);
            }
            //递归遍历出子文件下的文件,不需要的可以把childFolder设置为 false
            if (tempList[i].isDirectory() && childFolder) {
                ArrayList<File> files1 = getDirList(tempList[i].getPath(), childFolder);
                files.addAll(files1);
            }
        }
        return files;
    }

    /**
     * 检测某个目录下是否含有重名文件(夹):repetitionNum
     *
     * @param dirPath     目录地址
     * @param name        检测是否有重名的文件(夹)名
     * @param falgFile    是否检测文件 真为文件 假为文件夹
     * @param childFolder 是否包含子目录下 真为包含 假为不包括 一般不统计子文件夹可设置false即可
     *                    repetitionNum("C:\\Users\\p\\Desktop\\study","笔记",false,true);
     *                    repetitionNum("C:\\Users\\p\\Desktop\\study","笔记",false,false);
     *                    repetitionNum("C:\\Users\\p\\Desktop\\study","笔记2.md",true,true);
     *                    repetitionNum("C:\\Users\\p\\Desktop\\study","笔记2.md",true,false);
     * @return 返回对应目录下重名文件(夹)的数量
     */
    public static int repetitionNum(String dirPath, String name, boolean falgFile, boolean childFolder) {
        ArrayList<File> filesDir = new ArrayList<>();
        int count = 0;
        if (falgFile) {
            filesDir = getFilesList(dirPath, childFolder);
        } else {
            filesDir = getDirList(dirPath, childFolder);
        }
        for (File file : filesDir) {
            if (name.equals(file.getName())) {
                count++;
            }
        }
        return count;
    }




    /**
     * 检查目录是否存在,不存在则创建目录,只会创建目录不会创建文件的呦:createDirectory
     * "C:\\Users\\a\\b" ====>会创建到b文件夹
     * "C:\\Users\\a\\b\\" ====>会创建到b文件夹
     * 不能把路径精确到某个文件否则会出现如下bug:
     * "C:\\Users\\a\\b\\a.txt" ====>todo 会创建到a.txt文件夹,所以必须到文件夹不到具体文件路径
     *
     * @param path
     * @return
     */
    public static boolean createDirectory(String path) {
        boolean flag = false;
        File file = new File(path);
        if (!file.exists()) {
            flag = file.mkdirs();
        } else {
            // Log.getLogger().info("要创建的文件地址[" + path + "]存在!不需要创建!");
        }
        return flag;
    }

    /**
     * 由于上面会有个小bug 如下 所以在来个方法改进一下
     * "C:\\Users\\a\\b\\a.txt" ====>todo 会创建到a.txt文件夹, 解决如下
     * 必须这种形式传参:"C:\\Users\\h2h\\cc\\a.txt" 此时会创建到cc文件夹,a.txt只是来占位的
     * a.txt是随便写的,但是 是必须写的 todo  也就是说在你想创建目录下在随便写个文件即可,这个文件存不存在没关系
     *
     * @param path
     * @return
     */
    public static boolean createDirectory1(String path) {
        boolean flag = false;
        File file = new File(path);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        } else {
            // Log.getLogger().info("要创建的文件地址[" + path + "]存在!不需要创建!");
        }
        return flag;
    }

    /**
     * 检查目标路径文件是否存在,不存在则创建此目录及文件夹,会创建文件夹及文件:createDirectoryFile
     * "C:\\Users\\h1h\\a.txt" todo 请写到具体文件名的路径
     *
     * @param path
     * @return
     */
    public static boolean createDirectoryFile(String path) {
        boolean flag = false;
        File file = new File(path);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        if (!file.exists()) {
            try {
                flag = file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            // Log.getLogger().info("要创建的文件地址[" + path + "]存在!不需要创建!");
        }
        return flag;
    }

    /**
     * 判断文件是否存在如果存在就删除,不存在就新建:createNewFile
     * createNewFile("C:\\Users\\h1h\\a.txt");
     * 这个功能感觉不怎么常用,毕竟源文件存在你就给删了感觉风险有点高
     *
     * @param filePath
     */
    public static void createNewFile(String filePath) {
        File file = new File(filePath);
        if (file.exists()) {
            file.delete();
        } else {
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * 复制文件:copyFileToWriteFile
     * copyFileToWriteFile( "C:\\Users\\h1h\\a.txt","C:\\Users\\h2h\\cc\\b.txt")
     * 以上含义把a.txt复制到cc目录下并且重命名为b.txt
     *
     * @param sourceFilePath 文件源地址
     * @param targetFilePath 新文件地址
     */
    public static void copyFileToWriteFile(String sourceFilePath, String targetFilePath) {
        Writer writer = null;
        InputStream ins = null;
        createDirectory1(targetFilePath);
        try {
            writer = new FileWriter(targetFilePath);
            ins = new FileInputStream(new File(sourceFilePath));
            IOUtils.copy(ins, writer);
            ins.close();
        } catch (IOException e) {
            System.out.println("复制文件时出错,请检查!" + e);
        } finally {
            ins = null;
            IOUtils.closeQuietly(writer);
            IOUtils.closeQuietly(ins);
        }
    }


    /**
     * 复制文件 copyFile 跟上面 copyFileToWriteFile效果一致
     */
    public static boolean copyFile(String sourceFile, String targetFile) {
        File srcfile = new File(sourceFile);
        File destfile = new File(targetFile);

        try {
            FileUtils.copyFile(srcfile, destfile);
        } catch (IOException e) {
            System.out.println("复制文件[" + sourceFile + "]到指定位置[" + targetFile + "]时出错,请检查!");
            return false;
        } finally {
            if (null != srcfile) {
                srcfile = null;
            }
            if (null != destfile) {
                destfile = null;
            }
        }
        return true;
    }


    /**
     * 把文件复到一个文件夹:copyFileToDirectory
     * copyFileToDirectory(  "C:\\Users\\雷神\\Desktop\\ribao\\h1h\\a.txt",
     * "C:\\Users\\雷神\\Desktop\\ribao\\h2h\\cc"); 这里cc后有没有\\都行
     *
     * @param file
     * @param directory
     */
    public static void copyFileToDirectory(String file, String directory) {
        File srcfile = new File(file);
        File destDir = new File(directory);
        try {
            org.apache.commons.io.FileUtils.copyFileToDirectory(srcfile, destDir);
        } catch (IOException e) {
            // System.out.println("复制文件时出错,请检查!", e);
        } finally {
            srcfile = null;
            destDir = null;
        }
    }

    /**
     * 把文件夹下所有内容复制到指定文件夹下:copyFilesCope
     * copyFilesCope("C:\\Users\\h1h", "C:\\Users\\h2h\\cc");
     * 会把h1h文件下所有的内容 复制到cc文件夹下
     *
     * @param srcPath
     * @param targetPath
     */

    public static void copyFilesCope(String srcPath, String targetPath) {
        File src = new File(srcPath); //源文件夹
        File desc = new File(targetPath); //目标文件夹
        if (!desc.exists()) { //如果目标文件夹不存在
            desc.mkdirs(); //创建目标文件夹
        }
        long start = System.currentTimeMillis();
        try {
            copyFilesCope(src, desc); //复制文件夹
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void copyFilesCope(File src, File desc) throws IOException {
        if (src.isFile()) { //如果是文件
            FileInputStream fis = new FileInputStream(src);
            String path = desc.getAbsolutePath();
            FileOutputStream fos = new FileOutputStream(path);
            BufferedInputStream bis = new BufferedInputStream(fis);
            BufferedOutputStream bos = new BufferedOutputStream(fos);
            byte[] b = new byte[1024 * 1024];
            int len = 0;
            while ((len = bis.read(b)) != -1) {
                bos.write(b, 0, len);
            }
            bos.flush();
            bos.close();
            bis.close();
        } else { //如果是文件夹
            File[] files = src.listFiles(); //获取文件夹下的所有文件
            if (files.length == 0) { //如果文件夹为空
                String srcPath = src.getName(); //获取文件夹名称
                //拿到新文件夹的路径,新文件夹的路径为:目标文件夹的路径+文件夹名称
                String descPath = (desc.getAbsolutePath().endsWith("\\") ? desc.getAbsolutePath() : desc.getAbsolutePath() + "\\" + srcPath);
                File newFile = new File(descPath); //创建新文件夹
                if (!newFile.exists()) { //如果新文件夹不存在
                    newFile.mkdirs(); //创建新文件夹
                }
            } else { //如果文件夹不为空
                for (File f : files) { //遍历文件夹下的所有文件
                    String srcPath = f.getName(); //获取文件或文件夹的名称
                    String descPath = ""; //新文件夹的路径
                    if (f.isFile()) { //如果是文件
                        descPath = desc.getAbsolutePath() + "\\" + f.getName(); //新文件夹的路径为:目标文件夹的路径+文件夹名称
                    }
                    if (f.isDirectory()) { //如果是文件夹
                        //拿到新文件夹的路径,新文件夹的路径为:目标文件夹的路径+文件夹名称
                        descPath = (desc.getAbsolutePath().endsWith("\\") ? desc.getAbsolutePath() : desc.getAbsolutePath() + "\\" + srcPath);
                    }
                    File newFile = new File(descPath); //创建新文件夹
                    if (f.isDirectory()) { //如果是文件夹
                        if (!newFile.exists()) { //如果新文件夹不存在
                            newFile.mkdirs(); //创建新文件夹
                        }
                    }
                    copyFilesCope(f, newFile); //递归调用,此时拿到的newFile为目标路径,f为源路径
                }
            }
        }
    }

    /**
     * 复制文夹夹下的指定文件到目标文件夹:copyFileByName
     * copyFileByName("C:\\Users\\h2h\\b.txt",  "C:\\Users\\h2h\\cc");
     * todo 注意这块文件名是通过截取获得的,
     * 我记得 Linux下的路径分隔符是'/',而Windows下的路径分隔符是'\'。如果发生问题建议别用下面截取
     * 直接把名字当参数传进去即可
     *
     * @param oldFilePath
     * @param targetPath
     * @throws IOException
     */
    public static void copyFileByName(String oldFilePath, String targetPath) throws IOException {
        File file = new File(oldFilePath);
        File file2 = new File(targetPath);
        if (!file2.exists()) {
            file2.mkdirs();
        }
        if (file.exists()) {
            FileInputStream fis = new FileInputStream(file);
            String name = oldFilePath.substring(oldFilePath.lastIndexOf("\\") + 1, oldFilePath.length());
            FileOutputStream fos = new FileOutputStream(targetPath + File.separator + name);
            byte[] b = new byte[fis.available()];
            int len = 0;
            while ((len = fis.read(b)) != -1) {
                fos.write(b, 0, len);
                fos.flush();
            }
            fos.close();
            fis.close();
        }
    }

    /**
     * 获取指定文件夹下的指定类型的文件,然后复制到指定的文件夹下:copyFileByType
     * copyFileByType("C:\\Users\\h2h","C:\\Users\\h2h\\aa","txt");
     * todo  注意 本方法还支持把子文件夹下满足类型的文件也会找出来复制,我需求不需要给注释掉了,需要打开即可
     *
     * @param oldPath
     * @param newPath
     * @param fileType
     */
    public static void copyFileByType(String oldPath, String newPath, String fileType) {
        File files = new File(oldPath);
        File file2 = new File(newPath);
        if (!file2.exists()) {
            file2.mkdirs();
        }
        getAllFile(files, newPath, fileType);
    }

    //获取文件名称的方法
    public static void getAllFile(File file, String newPath, String fileType) {
        File[] files = file.listFiles();
        for (File fileName : files) {
            if (fileName.isDirectory()) {
                //如果是文件夹 也就是目标文件下的子文件夹 ,如果下面注释打开,会把子文件夹下满足的也找出来copy
//                getAllFile(fileName, newPath, fileType);
            } else {
                //如果是文件
                //获取文件的绝对路径
                String name = fileName.getAbsolutePath();
                if (name.endsWith("." + fileType)) {
                    //通过获取的路径进行文件的复制
                    //调用复制的方法
                    fileCopy(name, newPath);
                }
            }
        }
    }

    //文件复制方法
    public static void fileCopy(String str, String newPath) {
        //获取文件名称
        String substring = str.trim().substring(str.lastIndexOf("\\") + 1);
        FileReader fr = null;
        FileWriter fw = null;
        try {
            fr = new FileReader(str);
            fw = new FileWriter(newPath + File.separator + substring);

            int len = 0;
            char[] ch = new char[1024];
            while ((len = fr.read(ch)) != -1) {
                fw.write(ch, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //防止空指针异常
            if (fw != null && fr != null) {
                try {
                    fw.close();
                    fr.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    public static void main(String[] args) {

        FileUtil.copyFileToDirectory(
                "C:\\Users\\雷神\\Desktop\\ribao\\h1h\\a.txt",
                "C:\\Users\\雷神\\Desktop\\ribao\\h2h\\cc");
//        System.out.println(FileUtil.createDirectory1(
                "C:\\Users\\雷神\\Desktop\\ribao\\h2h\\cc\\b.txt"));
//                "C:\\Users\\雷神\\Desktop\\ribao\\h2h\\cc\\f"));
    }


    /**
     * 将字符串生成文件
     *
     * @param str            字符
     * @param targetFilePath 生成文件地址
     * @param encode         文件编码
     */
    public static void stringToFile(String str, String targetFilePath, String encode) {
        String strWrite = str;
        try {
            IOUtils.write(strWrite, new FileOutputStream(targetFilePath), encode);
        } catch (IOException e) {
            // System.out.println("字符串生成文件时出错,请检查!", e);
        } finally {
            strWrite = null;
        }
    }


    /**
     * 默认文件编码为utf-8的字符串转文件
     *
     * @param str
     * @param targetFilePath
     */
    public static void stringToFile(String str, String targetFilePath) {
        stringToFile(str, targetFilePath, "UTF-8");
    }

    /**
     * 将url地址变为字符串,
     *
     * @param urlPath  URL地址
     * @param encode   编码
     * @return
     */
    public static String urlToString(String urlPath, String encode) {
        String str = "";
        InputStream ins = null;
        try {
            URL url = new URL(urlPath);
            ins = url.openStream();
            str = IOUtils.toString(ins, encode);
            ins.close();
        } catch (MalformedURLException e) {
            System.out.println("URL地址格式错误,请检查!");
        } catch (IOException e) {
            System.out.println("文件流出错,请检查!");
        } finally {
            ins = null;
            IOUtils.closeQuietly(ins);
        }
        return str;
    }

    /**
     * 默认编码为utf-8的url转字符串
     *
     * @param urlPath
     * @return
     */
    public static String urlToString(String urlPath) {
        return urlToString(urlPath, "UTF-8");
    }

    /**
     * url生成文件
     *
     * @param urlPath         url地址
     * @param targetFilePath  生成文件地址
     * @param encode          编码
     */
    public static void urlToFile(String urlPath, String targetFilePath, String encode) {
        stringToFile(urlToString(urlPath, encode), targetFilePath, encode);

    }

    /**
     * 默认utf-8编码的url转文件
     *
     * @param urlPath
     * @param targetFilePath
     */
    public static void urlToFile(String urlPath, String targetFilePath) {
        stringToFile(urlToString(urlPath), targetFilePath);
    }

    /**
     * 删除目录下文件
     *
     * @param directory
     */
    public static void delDirectoryFiles(String directory) {
        File dir = new File(directory);
        try {
            org.apache.commons.io.FileUtils.cleanDirectory(dir);// 清空目录下的文件
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            dir = null;
        }
    }

    /**
     * 删除目录和目录下的文件
     *
     * @param directory
     */
    public static void delDirectoryAndFiles(String directory) {
        File dir = new File(directory);

        try {
            org.apache.commons.io.FileUtils.deleteDirectory(dir);// 删除目录和目录下的文件
        } catch (IOException e) {
            // System.out.println("删除目录与目录下的文件夹出错,请检查!", e);
        } finally {
            dir = null;
        }
    }

    /**
     * 目录大小
     *
     * @param directory
     * @return
     */
    public static Long getDirectorySize(String directory) {
        File file = new File(directory);
        long size = FileUtils.sizeOfDirectory(file);
        return size;
    }

    /**
     * 创建文件或修改文件时间,如果不存在新建,如果存在,修改文件修改时间
     *
     * @param path
     */
    public static void createDirectoryOrUpdateModifyDateTime(String path) {
        File file = new File(path);
        try {
            FileUtils.touch(file);
        } catch (IOException e) {
            // System.out.println("文件流出错,请检查!", e);
        } finally {
            file = null;
        }

    }

    /**
     * 文件变为字符串
     *
     * @param file    文件全地址
     * @param encode  编码
     * @return
     */
    public static String fileToString(String file, String encode) {
        String str = "";
        InputStream ins = null;
        try {
            ins = new FileInputStream(file);
            str = IOUtils.toString(ins, encode);
            ins.close();
        } catch (FileNotFoundException e) {
            // System.out.println("文件没有找到请检查文件地址!", e);
        } catch (IOException e) {
            // System.out.println("文件流出错,请检查!", e);
        } finally {
            ins = null;
            IOUtils.closeQuietly(ins);
        }
        return str;
    }

    /**
     * 默认编码utf-8的文件变为字符串
     *
     * @param file
     * @return
     */
    public static String fileToString(String file) {
        return fileToString(file, "UTF-8");
    }

    /**
     * 没用使用IOUtils工具类的文件转字符串
     *
     * @param fielPath
     * @return
     */
    public static String fileToStringWithOutIOUtils(String fielPath, String encode) {

        StringBuffer sb = null;
        FileInputStream fis = null;
        InputStreamReader isr = null;
        BufferedReader in = null;
        try {
            fis = new FileInputStream(fielPath);
            isr = new InputStreamReader(fis, encode);
            in = new BufferedReader(isr);

            String s = new String();
            sb = new StringBuffer();
            while ((s = in.readLine()) != null) {
                sb.append(s + "\n");
            }
            in.close();
            isr.close();
            fis.close();
        } catch (FileNotFoundException e) {
            // System.out.println("文件不存在请检查!", e);
        } catch (UnsupportedEncodingException e) {
            // System.out.println("不被支持的编码,请检查!", e);
        } catch (IOException e) {
            // System.out.println("IO文件操作错误,请检查", e);
        } finally {
            in = null;
            isr = null;
            fis = null;
        }
        return sb.toString();
    }

    /**
     * 使用默认编码为utf-8的文件变字符串
     *
     * @param fielPath
     * @return
     */
    public static String fileToStringWithOutIOUtils(String fielPath) {
        return fileToStringWithOutIOUtils(fielPath, "UTF-8");
    }

    /**
     * 传入流生成文件 Mr_Arthur 2013-4-12 上午12:54:50
     *
     * @param is       传入的流
     * @param filePath 生成文件地址
     * @return
     */
    public static Integer inputStreamToFile(InputStream is, String filePath) {
        Integer result = 0;
        FileOutputStream out = null;
        try {
            out = new FileOutputStream(filePath);
            byte[] buf = new byte[1024];
            int len;
            while ((len = is.read(buf)) > 0) {
                out.write(buf, 0, len);
            }
            result = 1;
        } catch (FileNotFoundException e) {
            result = 0;
            // System.out.println("文件没有生成,请检查!", e);
        } catch (IOException e) {
            result = 0;
            // System.out.println("IO操作错误,无法生成文件!", e);
        } finally {
            try {
                is.close();
                out.close();
            } catch (IOException e) {
                result = 0;
                // System.out.println("IO关闭错误!", e);
            }
        }
        return result;
    }

    /**
     * reader转文件
     * <p>
     * Mr_Arthur 2013-4-13 上午3:57:33
     *
     * @param reader
     * @param filePath
     * @param encode
     * @return
     */
    @SuppressWarnings("deprecation")
    public static Integer readerToFile(Reader reader, String filePath, String encode) {
        Integer result = 0;

        try {
            stringToFile(IOUtils.toString(IOUtils.toByteArray(reader, encode)), filePath);
            result = 1;
        } catch (IOException e) {
            result = 0;
            // System.out.println("reader转文件出错!请检查!", e);
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    // System.out.println("流关闭出错!", e);
                }
            }
        }
        return result;
    }

    public static byte[] getBytesFromFile(File f) throws Exception {
        FileInputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream(f);
            byte[] b = new byte[fileInputStream.available()];
            fileInputStream.read(b);
            return b;
        } catch (Exception e) {
            throw e;
        } finally {
            try {
                if (fileInputStream != null) {
                    fileInputStream.close();
                }
            } catch (IOException e) {
            }
        }

    }

    public static void wirteDataToFile(String savePath, byte[] data) throws Exception {
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream(savePath);
            fileOutputStream.write(data);
            fileOutputStream.flush();
        } catch (Exception e) {
            throw e;
        } finally {
            try {
                if (fileOutputStream != null) {
                    fileOutputStream.close();
                }
            } catch (IOException e) {
            }
        }
    }


    /**
     * 清空指定文件夹下所有内容:delAllFile     不会删除此目录只是清空此目录下的所有内容
     * delAllFile("C:\\Users\\h2h");
     * h2h目录会变成空文件夹
     *
     * @return
     */
    public static boolean delAllFile(String path) {
        boolean flag = false;
        File file = new File(path);
        if (!file.exists()) {
            return flag;
        }
        if (!file.isDirectory()) {
            return flag;
        }
        String[] tempList = file.list();
        File temp = null;
        for (int i = 0; i < tempList.length; i++) {
            if (path.endsWith(File.separator)) {
                temp = new File(path + tempList[i]);
            } else {
                temp = new File(path + File.separator + tempList[i]);
            }
            if (temp.isFile()) {
                temp.delete();
            }
            if (temp.isDirectory()) {
                delAllFile(path + "/" + tempList[i]);//先删除文件夹里面的文件
                delFolder(path + "/" + tempList[i]);//再删除空文件夹
                flag = true;
            }
        }
        return flag;
    }

    /**
     * 删除指定文件夹及下所有内容:delFolder   会删除此文件夹及下面所有内容
     * delFolder("C:\\Users\\h2h");
     * h2h目录会被删除掉
     */
    public static void delFolder(String folderPath) {
        try {
            delAllFile(folderPath); //删除完里面所有内容
            String filePath = folderPath;
            filePath = filePath.toString();
            File myFilePath = new File(filePath);
            myFilePath.delete(); //删除空文件夹
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * new File("C:\\Users\\h2h")
     * h2h目录会变成空文件夹
     * todo 效果与delAllFile一致但是看起来更加简洁
     *
     * @param file
     */
    public static void removeDirectory(File file) {
        //将file子目录及子文件放进文件数组
        File[] files = file.listFiles();
        //如果包含文件进行删除操作
        if (files != null) {
            for (int i = 0; i < files.length; i++) {
                //删除子文件
                if (files[i].isFile()) {
                    files[i].delete();
                } else if (files[i].isDirectory()) {
                    //通过递归方法删除子目录的文件
                    removeDirectory(files[i]);
                }
                files[i].delete();//删除子目录
            }
        }
    }

    /**
     * File类的delete()、File类的deleteOnExit()、Files.delete(Path path)、Files.deleteIfExists(Path path);
     * 四个方法都可以删除文件或文件夹,它们的共同点是:
     * 当文件夹中包含子文件的时候都会删除失败,也就是说这四个方法只能删除空文件夹。
     * new File("C:\\Users\\h2h")
     * h2h目录会被删除掉
     * todo 效果与delFolder一致但是看起来更加简洁
     */
    public static void removeDirectoryAll(File file) {
        //清空文夹下内容使之变为空文件
        removeDirectory(file);
        //删除空文件
        file.deleteOnExit();
    }


   /**
     * 删除指定路径下的单个文件:deleteFile
     * deleteFile("C:\\Users\\c.txt")
     *
     * @param sPath 被删除文件的文件名的 todo 绝对路径
     * @return 单个文件删除成功返回true,否则返回false
     */
    public static boolean deleteFile(String sPath) {
        boolean flag;
        flag = false;
        File file = new File(sPath);
        // 路径为文件且不为空则进行删除
        if (file.isFile() && file.exists()) {
            file.delete();
            flag = true;
        }
        return flag;
    }

    /**
     * 删除指定路径下的多个文件:deleteFileList
     * List<String> list = new ArrayList<>();
     * Collections.addAll(list, "a.txt", "c.txt");
     * System.out.println(deleteFileList("C:\\Users\\h1h", list));
     *
     * @param sPath     todo 删除文件的文件夹路径
     * @param fileNames 路径下的文件名全称
     * @return 文件删除成功返回true,否则返回false
     */
    public static boolean deleteFileList(String sPath, List<String> fileNames) {
        boolean flag;
        flag = false;
        //如果sPath不以文件分隔符结尾,自动添加文件分隔符
        if (!sPath.endsWith(File.separator)) {
            sPath = sPath + File.separator;
        }
        if (!isDirectoryOrFile(sPath)) {
            return false;
        }
        for (String fileName : fileNames) {
            File file = new File(sPath + fileName);
            // 路径为文件且不为空则进行删除
            if (file.isFile() && file.exists()) {
                file.delete();
                flag = true;
            }
        }
        return flag;
    }


    /**
     * 暴力删除,直接删除掉你指定的文件夹及目录下所有内容:deleteDirectoryAll
     * deleteDirectoryAll("C:\\Users\\h2h")  直接把h2h目录干掉了
     * 如果不想删除掉子目录下的文件,可注释掉对应代码
     *
     * @param sPath
     * @return
     */
    public static boolean deleteDirectoryAll(String sPath) {
        boolean flag = false;
        //如果sPath不以文件分隔符结尾,自动添加文件分隔符
        if (!sPath.endsWith(File.separator)) {
            sPath = sPath + File.separator;
        }
        File dirFile = new File(sPath);
        //如果dir对应的文件不存在,或者不是一个目录,则退出
        if (!dirFile.exists() || !dirFile.isDirectory()) {
            return false;
        }
        flag = true;
        //删除文件夹下的所有文件(包括子目录)
        File[] files = dirFile.listFiles();
        for (int i = 0; i < files.length; i++) {
            //删除子文件
            if (files[i].isFile()) {
                flag = deleteFile(files[i].getAbsolutePath());
                if (!flag) {
                    break;
                }
            } //删除子目录(todo 如果不想删除掉子目录可注释掉)
            else {
                flag = deleteDirectoryAll(files[i].getAbsolutePath());
                if (!flag) {
                    break;
                }
            }
        }
        if (!flag) {
            return false;
        }
        //删除当前目录
        if (dirFile.delete()) {
            return true;
        } else {
            return false;
        }

    }



    /**
     * 删除指定文件夹下指定文件名:circleMethod
     * circleMethod("C:\\Users\\h2h\\cc","a.txt");
     *
     * @param dirPath
     */
    private static void circleMethod(String dirPath, String fileName) {
        File file = new File(dirPath);
        if (file.isDirectory()) {
            String[] dirPathList = file.list();
            for (int i = 0; i < dirPathList.length; i++) {
                String filePath = dirPath + File.separator + dirPathList[i];
                File fileDelete = new File(filePath);
                if (fileDelete.getName().equals(fileName)) {
                    fileDelete.delete();
                }
            }
        }
    }

    /**
     * 删除指定文件夹下多个指定文件名:delMethod
     * delMethod("C:\\Users\\h2h","c.txt,e.log,f.bat,s.net");
     *
     * @param filePath  文件路径
     * @param fileNames 文件名称 逗号分割
     */
    public static void delMethod(String filePath, String fileNames) {
        //多个文件,逗号分割
        String[] name = fileNames.split(",");
        for (String fileName : name) {
            File file = new File(filePath + "\\" + fileName);
            if (file.exists() && file.isFile()) {
                file.delete();
            }
        }
    }

    /**
     * 指定文件重命名:reNameFile
     * reNameFile("C:\\Users\\h3hh\\d.txt", "C:\\Users\\h3hh\\abc.log");
     * 注意路径地址就最后一位不一致
     *
     * @param oldFilePath
     * @param newFilePath
     */
    public static void reNameFile(String oldFilePath, String newFilePath) {
        File oldName = new File(oldFilePath);
        File newName = new File(newFilePath);
        oldName.renameTo(newName);
    }

    /**
     * 删除目标文件夹下指定文件格式的所有文件:circleMethodType
     * circleMethod("C:\\Users\\h2h\\cc","txt");
     *
     * @param dirPath
     */
    private static void circleMethodType(String dirPath, String fileType) {
        File file = new File(dirPath);
        if (file.isDirectory()) {
            String[] dirPathList = file.list();
            for (int i = 0; i < dirPathList.length; i++) {
                String filePath = dirPath + File.separator + dirPathList[i];
                File fileDelete = new File(filePath);
                if (fileDelete.getName().contains("." + fileType)) {
                    fileDelete.delete();
                }
            }
        }
    }

    //检查是否有重名 :duplicateName
    public static boolean duplicateName(List<File> list, String targetFilePath) {
        File targetFile = new File(targetFilePath);
        for (File file : list) {
            if (file.getName().equals(targetFile.getName())) {
                return true;
            }
        }
        return false;
    }
    //检查是否有重名 :duplicateName
    public static boolean duplicateName(List<File> list, File targetFilePath) {
        for (File file : list) {
            if (file.getName().equals(targetFilePath.getName())) {
                return true;
            }
        }
        return false;
    }

    //重名后的新的起名名称:getNewName
    public static String getNewName(String oldAbsolutePath, int no) {
        File file = new File(oldAbsolutePath);
        if (file.isFile()) {
            String name = file.getName();
            String type = "." + getFileNameOrType(name, "2");
            name = getFileNameOrType(name, "1");
            name = name + "(" + (no) + ")";
            return name + type;
        }
        if (file.isDirectory()) {
            String name = file.getName();
            name = name + "(" + (no) + ")";
            return name;
        }
        return null;
    }


    /**
     * 指定文件夹重命名:reNameDirectory
     * reNameDirectory("C:\\Users\\h22h", "C:\\Users\\h3hh");
     * 注意路径地址就最后一位不一致
     *
     * @param oldDir
     * @param newDir
     */
    public static void reNameDirectory(String oldDir, String newDir) {
        File folder = new File(oldDir);
        File newfolder = new File(newDir);
        folder.renameTo(newfolder);
    }


    /**
     * 批量修改文件名字:modifyFileNames
     * modifyFileNames("C:\\Users\\ribao\\h2h")
     * 这个方法没有写灵活参数,根据你的需求更新文件名吧
     * 如果是目录我这里直接跳过了,你如果想批量改目录就跳过文件即可
     *
     * @param filePath
     */
    public static void modifyFileNames(String filePath) {
        //  找到存放需要修改文件名的文件所在文件夹
        File file = new File(filePath);
        File[] list = file.listFiles();
        if (file.exists() && file.isDirectory()) {
            //for循环实现批量处理文件
            for (int i = 0; i < list.length; i++) {
                if (!list[i].getName().contains(".")) {
                    //如果是目录则跳过
                    continue;
                }
                String name = list[i].getName();
                int index = name.indexOf(0);
                //  将文件名更改为abc+原文件名
                String newName = "abc";
                String name2 = newName + name.substring(index + 1);
                //  将文件保存回原文件夹
                File dest = new File(filePath + File.separator + name2);
                list[i].renameTo(dest);
            }
        }
    }

    /**
     * 这个我就不测试了,怎么说呢,这的根据你的需求命名规则来实现 换下命名条件没啥懒得 recursiveTraversalFolder
     *
     * @param path
     */
    public static void recursiveTraversalFolder(String path) {
        File folder = new File(path);
        if (folder.exists()) {
            File[] fileArr = folder.listFiles();
            if (null == fileArr || fileArr.length == 0) {
                System.out.println("文件夹是空的!");
                return;
            } else {
                File newDir = null;//文件所在文件夹路径+新文件名
                String newName = "";//新文件名
                String fileName = null;//旧文件名
                File parentPath = new File("");//文件所在父级路径
                for (File file : fileArr) {
                    if (file.isDirectory()) {//是文件夹,继续递归,如果需要重命名文件夹,这里可以做处理
                        System.out.println("文件夹:" + file.getAbsolutePath() + ",继续递归!");
                        recursiveTraversalFolder(file.getAbsolutePath());
                    } else {//是文件,判断是否需要重命名
                        fileName = file.getName();
                        parentPath = file.getParentFile();
                        if (fileName.contains("abc")) {//文件名包含需要被替换的字符串
                            newName = fileName.replaceAll("abc", "gg");//新名字
                            newDir = new File(parentPath + "/" + newName);//文件所在文件夹路径+新文件名
                            file.renameTo(newDir);//重命名
                            System.out.println("修改后:" + newDir);
                        }
                    }
                }
            }
        } else {
            System.out.println("文件不存在!");
        }
}



    /**
     * 获取文件名称前缀与后缀:getFileNameOrType
     * getFileNameOrType("ab.c.ds.pdf", "1") ===>ab.c.ds     pdf
     * @param fileName
     * @param flag
     * @return
     */
    public static String getFileNameOrType(String fileName,String flag){
        if ("1".equals(flag)){
            return fileName.substring(0,fileName.lastIndexOf("."));
        }
        return fileName.substring(fileName.lastIndexOf(".")+1);
    }

	/**
     * 我们通常需要获取路径最后一个/的位置来做截取操作
     * 返回路径中最后/出现的位置:getLastIndexOfGang
     * getLastIndexOfGang("test3\\tes\\t3.log");//   9
     * "test3\\tes\\t3.log".substring(0,9);//  test3\tes
     * "test3\\tes\\t3.log".substring(10);//   t3.log
     * todo 技巧 \\实际就是一个\
     * @param filePath
     * @return
     */
    public static int getLastIndexOfGang(String filePath){
       return filePath.lastIndexOf(File.separator);
    }

    /**
     * 获取上一级目录:getParentPath
     * getParentPath("C:\\Users\\h1h");          //C:\Users
     * getParentPath("C:\\Users\\h1h\\a.txt");  //C:\Users\h1h
     */
    public static String getParentPath(String path) {
        File file = new File(path);
        File parentFile = file.getParentFile();
        return parentFile.getAbsolutePath();
    }

   /**
     * 如果sPath不以文件分隔符结尾,自动添加文件分隔符:getNeedPath
     * @param sPath
     * @return
     */
    public static String getNeedPath(String sPath){
        if (!sPath.endsWith(File.separator)) {
            sPath = sPath + File.separator;
        }
        return sPath;
    }

 /**
     * 实现动态根据文件夹路径或者文件路径,如果路径不存在则创建此文件,并是否创建出文件:createDirectoryOrFile
     * createDirectoryOrFile("C:\\Users\\s.txt", false,true);
     * createDirectoryOrFile("C:\\Users", true,false);
     * @param path 随便给的路径地址(可以是文件夹或者到具体文件)
     * @param directoryPath 是否为文件夹路径 这个是就是不是就不是别乱写
     * @param directoryPath 是否创建此文件
     * @return
     */
    public static boolean createDirectoryOrFile(String path,boolean directoryPath , boolean createFile) {
        File file = new File(path);
        if (directoryPath) {
            if (! file.exists()) {
                return file.mkdirs();
            }
        }else {
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }
            if (createFile) {
                try {
                  return   file.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return true;
    }

    /**
     * linuxPath("C:\\Users\\Desktop\\ri\\h2h") ===> C:/Users/Desktop/ri/h2h
     * file.separator在 UNIX 系统上,此字段的值为 '/';在 Microsoft Windows 系统上,它为 '\\'。
     * 修复路径,将 \\ 或 / 等替换为 File.separator:linuxPath
     * @param path
     * @return
     */
    public static String linuxPath(String path) {
        String p = StringUtils.replace(path, "\\", "/");
        p = StringUtils.join(StringUtils.split(p, "/"), "/");
        if (!StringUtils.startsWithAny(p, "/") && StringUtils.startsWithAny(path, "\\", "/")) {
            p += "/";
        }
        if (!StringUtils.endsWithAny(p, "/") && StringUtils.endsWithAny(path, "\\", "/")) {
            p = p + "/";
        }
        return p;
    }

压缩这块分好几种情况 涉及内容较多单独拿到这块

/**
 * todo 压缩及解压缩篇
 *注意 (压缩这块一般设置的是保留原来路径结构,不保留的话会压缩到一个路径下,
 * 重名文件会导致报错,所以不保留目录结构时要重命名同名文件)对应方法已写:见类:ZipUtils
 * 压缩指定文件夹到指定文件夹(压缩单个文件夹下所有内容):
 * fileDirectoryToZip、toZip1 (是fileDirectoryToZip的升级版本)
 * 压缩指定文件到指定文件夹(单个压缩指定文件):toZip1 
 * 多个文件压缩到一起到到指定文件夹压缩包(压缩多个文件夹)
 * 多个文件夹压缩到一起到到指定文件夹压缩包(压缩多个文件):zipFiles
 * 压缩指定文件夹后生成压缩文件(zip、rar 格式):generateFile、toZip1 、
 * zipFiles(可针对多文件、单文件)
 * (压缩文件格式这块貌似改下后缀就好用)
 * 不保留目录结构时重命名同名文件:ZipUtils .zip
 * 
 * 解压缩 可以解压zip、rar其他格式没试 压缩文件到指定文件夹下:decompress
 * 解压这块好像只要是压缩格式都能解压:releaseZipToFile 跟上面效果一致推荐使用

 */
import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
  *把指定文件夹下所有内容压缩到指定文件夹并起名为 XXX.zip:fileDirectoryToZip
  * @param srcDir 要压缩的文件夹
  * @param outZipDir  压缩包的位置文件夹+压缩包名称
  * @param KeepDirStructure true表示保留压缩前的目录结构,false表示不保留原目录结构
  *     所有文件都放在压缩同一级目录,这样就会有个问题,不同文件夹下若是有同名文件会报错导致压缩失败
  *   fileDirectoryToZip("C:\\Users\\h2h", "C:\\Users\\gg\\压缩包名称.zip",false);
     */
    public static boolean fileDirectoryToZip(String srcDir, String outZipDir, boolean KeepDirStructure) {
        if (KeepDirStructure){
            System.out.println("请确认压缩文件夹下子文件夹不存在同名文件(即所有文件名唯一),否则会压缩失败,\n" +
                    "建议设置为false,保留原文件目录格式");
        }
        File file = new File(srcDir);
        if (!file.isDirectory()) {
            return false;
        }
        File lastZipFile = new File(outZipDir);
        File parentFile = lastZipFile.getParentFile();
        //判断是否存在
        if (!parentFile.exists()) {
            // 创建父目录文件夹
            parentFile.mkdirs();
        }
        FileOutputStream fos2 = null;
        try {
            fos2 = new FileOutputStream(lastZipFile);
            System.out.println(srcDir + "目录压缩到: " + outZipDir);
            toZip(srcDir, fos2, KeepDirStructure);
            return true;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return false;
    }
    public static void toZip(String srcDir, OutputStream out, boolean KeepDirStructure) throws RuntimeException {
        long start = System.currentTimeMillis();
        ZipOutputStream zos = null;
        try {
            zos = new ZipOutputStream(out);
            File sourceFile = new File(srcDir);
            compress(sourceFile, zos, sourceFile.getName(), KeepDirStructure);
            long end = System.currentTimeMillis();
            System.out.println("压缩完成,耗时:" + (end - start) + " ms");
        } catch (Exception e) {
            throw new RuntimeException("压缩失败 zip error from ZipUtils", e);
        } finally {
            if (zos != null) {
                try {
                    zos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 递归压缩方法
     *
     * @param sourceFile       源文件
     * @param zos              zip输出流
     * @param name             压缩后的名称
     * @param KeepDirStructure 是否保留原来的目录结构,true:保留目录结构;
     *                         false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败)
     * @throws Exception
     */

    private static void compress(File sourceFile, ZipOutputStream zos, String name, boolean KeepDirStructure) throws Exception {
        byte[] buf = new byte[2 * 1024];
        if (sourceFile.isFile()) {
            // 向zip输出流中添加一个zip实体,构造器中name为zip实体的文件的名字
            zos.putNextEntry(new ZipEntry(name));
            // copy文件到zip输出流中
            int len;
            FileInputStream in = new FileInputStream(sourceFile);
            while ((len = in.read(buf)) != -1) {
                zos.write(buf, 0, len);
            }
            // Complete the entry
            zos.closeEntry();
            in.close();
        } else {
            File[] listFiles = sourceFile.listFiles();
            if (listFiles == null || listFiles.length == 0) {
                // 需要保留原来的文件结构时,需要对空文件夹进行处理
                if (KeepDirStructure) {
                    // 空文件夹的处理
                    zos.putNextEntry(new ZipEntry(name + "/"));
                    // 没有文件,不需要文件的copy
                    zos.closeEntry();
                }
            } else {
                for (File file : listFiles) {
                    // 判断是否需要保留原来的文件结构
                    if (KeepDirStructure) {
                        // 注意:file.getName()前面需要带上父文件夹的名字加一斜杠,
                        // 不然最后压缩包中就不能保留原来的文件结构,即:所有文件都跑到压缩包根目录下了
                        compress(file, zos, name + "/" + file.getName(), KeepDirStructure);
                    } else {
                        compress(file, zos, file.getName(), KeepDirStructure);
                    }
                }
            }
        }
    }

上面仅仅针对文件夹操作 ,这个能针对单个文件或文件进行压缩

import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;


/**
 * 可以压缩指定文件夹或者指定文件:toZip1
 * @param source      待压缩文件/文件夹路径
 * @param destination 压缩后压缩文件路径
 *   toZip1("C:\\Users\\a.txt","C:\\Users\\Desktop\\文件压缩名.zip")
 *   toZip1("C:\\Users\\h2h","C:\\Users\\Desktop\\文件夹压缩名.zip")
 * @return
 */
    public static boolean toZip1(String source, String destination) {
        try {
            FileOutputStream out = new FileOutputStream(destination);
            ZipOutputStream zipOutputStream = new ZipOutputStream(out);
            File sourceFile = new File(source);
            // 递归压缩文件夹
            compress1(sourceFile, zipOutputStream, sourceFile.getName());
            zipOutputStream.flush();
            zipOutputStream.close();
        } catch (IOException e) {
            System.out.println("failed to zip compress, exception");
            return false;
        }
        return true;
    }


    private static void compress1(File sourceFile, ZipOutputStream zos, String name) throws IOException {
        byte[] buf = new byte[1024];
        if (sourceFile.isFile()) {
            // 压缩单个文件,压缩后文件名为当前文件名
            zos.putNextEntry(new ZipEntry(name));
            // copy文件到zip输出流中
            int len;
            FileInputStream in = new FileInputStream(sourceFile);
            while ((len = in.read(buf)) != -1) {
                zos.write(buf, 0, len);
            }
            zos.closeEntry();
            in.close();
        } else {
            File[] listFiles = sourceFile.listFiles();
            if (listFiles == null || listFiles.length == 0) {
                // 空文件夹的处理(创建一个空ZipEntry)
                zos.putNextEntry(new ZipEntry(name + "/"));
                zos.closeEntry();
            } else {
                // 递归压缩文件夹下的文件
                for (File file : listFiles) {
                    compress1(file, zos, name + "/" + file.getName());
                }
            }
        }
    }

上面都是单压缩 下面说说多压缩

import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;


/**
     * 多个文件夹压缩到一起到到指定文件夹压缩包(压缩多个文件):zipFiles
     * @param srcFilePathArray  目标路径下的文件数组
     * @param zipFilePath 打成压缩包的名称及格式支持zip、rar
     * String zipFilePath = "C:\\Users\\fc.zip";
     * String[] srcFilePathArray = {"C:\\Users\\h1h\\a.txt",
     * "C:\\Users\\h2h\\aa\\h.txt",
     * "C:\\Users\\ribao\\20220327.xls"};
     * zipFiles(srcFilePathArray, zipFilePath)
     * @return
     */
    public static boolean zipFiles(String[] srcFilePathArray, String zipFilePath) {
        File[] srcfile = new File[srcFilePathArray.length];
        for (int i = 0; i < srcfile.length; i++) {
            srcfile[i] = new File(srcFilePathArray[i]);
        }
        File zipFile = new File(zipFilePath);
        return zipFiles(srcfile, zipFile);
    }

    /**
     * 功能:压缩多个文件成一个zip、rar文件
     *
     * @param srcfile:源文件列表
     * @param zipfile:压缩后的文件
     */
    public static boolean zipFiles(File[] srcfile, File zipfile) {
        boolean reFlag = false;
        byte[] buf = new byte[10240];
        ZipOutputStream out = null;
        FileInputStream in = null;
        try {
            //ZipOutputStream类:完成文件或文件夹的压缩
            out = new ZipOutputStream(new FileOutputStream(zipfile));
            //注意此处编码设置
            out.setEncoding("UTF-8");
            for (int i = 0; i < srcfile.length; i++) {
                in = new FileInputStream(srcfile[i]);
                out.putNextEntry(new ZipEntry(srcfile[i].getName()));
                int len;
                while ((len = in.read(buf)) > 0) {
                    out.write(buf, 0, len);
                }
                out.closeEntry();
                in.close();
                in = null;
            }
            out.close();
            out = null;
            reFlag = true;
            System.out.println("压缩完成,文件详细信息为:" + zipfile.getAbsolutePath());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (in != null) {
                try {
                    in.close();
                    in = null;
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (out != null) {
                try {
                    out.close();
                    out = null;
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return reFlag;
    }

压缩指定文件夹后生成压缩文件(zip、rar 格式):generateFile

/**
     * 压缩指定文件夹后生成压缩文件(zip、rar 格式):generateFile
     * @param path 要压缩的文件路径
     * @param tarPath 压缩后的文件路径及对应压缩文件格式
     *             支持生成的格式(zip、rar) 注意tarPath路径要到压缩文件名+压缩文件格式
     *             generateFile("C:\\Users\\rib\\h2h", "C:\\Users\\rib\\aaa.rar");
     *             generateFile("C:\\Users\\rib\\h2h", "C:\\Users\\rib\\aaa.zip");
     */
    public static void generateFile(String path, String tarPath) throws Exception {
        File file = new File(path);
        // 压缩文件的路径不存在
        if (!file.exists()) {
            throw new Exception("路径 " + path + " 不存在文件,无法进行压缩...");
        }
        // 用于存放压缩文件的文件夹
        String generateFile = tarPath;
        File compress = new File(generateFile);
        // 如果文件夹不存在,进行创建
        if (!compress.getParentFile().exists()) {
            compress.getParentFile().mkdirs();
        }
        // 目的压缩文件
        String generateFileName = compress.getAbsolutePath();
        // 输入流 表示从一个源读取数据
        // 输出流 表示向一个目标写入数据

        // 输出流
        FileOutputStream outputStream = new FileOutputStream(generateFileName);

        // 压缩输出流
        ZipOutputStream zipOutputStream = new ZipOutputStream(new BufferedOutputStream(outputStream));

        generateFile(zipOutputStream, file, "");

        System.out.println("源文件位置:" + file.getAbsolutePath() + ",目的压缩文件生成位置:" + generateFileName);
        // 关闭 输出流
        zipOutputStream.close();
    }

    /**
     * @param out  输出流
     * @param file 目标文件
     * @param dir  文件夹
     * @throws Exception
     */
    private static void generateFile(ZipOutputStream out, File file, String dir) throws Exception {
        // 当前的是文件夹,则进行一步处理
        if (file.isDirectory()) {
            //得到文件列表信息
            File[] files = file.listFiles();
            //将文件夹添加到下一级打包目录
            out.putNextEntry(new ZipEntry(dir + "/"));
            dir = dir.length() == 0 ? "" : dir + "/";
            //循环将文件夹中的文件打包
            for (int i = 0; i < files.length; i++) {
                generateFile(out, files[i], dir + files[i].getName());
            }
        } else { // 当前是文件
            // 输入流
            FileInputStream inputStream = new FileInputStream(file);
            // 标记要打包的条目
            out.putNextEntry(new ZipEntry(dir));
            // 进行写操作
            int len = 0;
            byte[] bytes = new byte[1024];
            while ((len = inputStream.read(bytes)) > 0) {
                out.write(bytes, 0, len);
            }
            // 关闭输入流
            inputStream.close();
        }
    }

解压缩 可以解压zip、rar 压缩文件到指定文件夹下:decompress

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.charset.Charset;
import java.util.zip.CRC32;
import java.util.zip.CheckedInputStream;

import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;


/**
     * 解压缩 可以解压zip、rar 压缩文件到指定文件夹下:decompress
     * String zipFilePath = "C:\\Users\\zz.rar";
     *  String tarUnZipPath = "C:\\Users\\cc\\bb";
     *  decompress(zipFilePath,tarUnZipPath );
     * @param srcFile 压缩文件绝对路径
     * @param destPath 解压后的文件位置
     * 注意:这里会把zz.rar下的所有文件(夹)直接解压到bb目录下,并不会在bb下创建个zz文件夹,如果你有需求可以加
     */
    public static void decompress(File srcFile, String destPath) throws Exception {
        decompress(srcFile, new File(destPath));
    }

    /**
     * 解压缩
     * @param srcFile
     * @param destFile
     * @throws Exception
     */
    public static void decompress(File srcFile, File destFile) throws Exception {
        CheckedInputStream cis = new CheckedInputStream(new FileInputStream(srcFile), new CRC32());
        ZipInputStream zis = new ZipInputStream(cis, Charset.forName("GBK"));
        decompress(destFile, zis);
        zis.close();

    }



    /**
     * 文件 解压缩
     *
     * @param srcPath  源文件路径
     * @param destPath 目标文件路径
     * @throws Exception
     */
    public static void decompress(String srcPath, String destPath) throws Exception {
        File srcFile = new File(srcPath);
        decompress(srcFile, destPath);
    }

    /**
     * 文件 解压缩
     *
     * @param destFile 目标文件
     * @param zis      ZipInputStream
     * @throws Exception
     */
    private static void decompress(File destFile, ZipInputStream zis) throws Exception {
        ZipEntry entry = null;
        while ((entry = zis.getNextEntry()) != null) {
            // 文件
            String dir = destFile.getPath() + File.separator + entry.getName();
            File dirFile = new File(dir);
            // 文件检查
            fileProber(dirFile);
            if (entry.isDirectory()) {
                dirFile.mkdirs();
            } else {
                decompressFile(dirFile, zis);
            }
            zis.closeEntry();
        }
    }

    /**
     * 文件探针
     * 当父目录不存在时,创建目录!
     *
     * @param dirFile
     */
    private static void fileProber(File dirFile) {
        File parentFile = dirFile.getParentFile();
        if (!parentFile.exists()) {
            // 递归寻找上级目录
            fileProber(parentFile);
            parentFile.mkdir();
        }
    }

    /**
     * 文件解压缩
     *
     * @param destFile 目标文件
     * @param zis      ZipInputStream
     * @throws Exception
     */
    private static void decompressFile(File destFile, ZipInputStream zis) throws Exception {
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile));
        int count;
        byte data[] = new byte[1024];
        while ((count = zis.read(data, 0, 1024)) != -1) {
            bos.write(data, 0, count);
        }
        bos.close();
    }

这个比上面精简,可能是导入依赖的原因,上面用的是jdk自带的,
两者功能一样但是个人推荐使用这个

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;

import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;


    /**
     * 解压这块好像只要是压缩格式都能解压:releaseZipToFile
     * releaseZipToFile("G:\\changeFile.jar", "G:\\test");
     * 测试解压缩功能. 将G:\\changeFile.jar连同子目录解压到G:\\test目录下.
     *  releaseZipToFile("C:\\Users\\h2h5.zip","C:\\Users\\cc\\bb");
     * @throws Exception
     */
    public static void releaseZipToFile(String sourceZip, String outFileName)
            throws IOException {
        ZipFile zfile = new ZipFile(sourceZip);
        Enumeration<?> zList = zfile.getEntries();
        ZipEntry ze = null;
        byte[] buf = new byte[1024];
        while (zList.hasMoreElements()) {
            // 从ZipFile中得到一个ZipEntry
            ze = (ZipEntry) zList.nextElement();
            if (ze.isDirectory()) {
                continue;
            }
            // 以ZipEntry为参数得到一个InputStream,并写到OutputStream中
            OutputStream os = new BufferedOutputStream(new FileOutputStream(
                    getRealFileName(outFileName, ze.getName())));
            InputStream is = new BufferedInputStream(zfile.getInputStream(ze));
            int readLen = 0;
            while ((readLen = is.read(buf, 0, 1024)) != -1) {
                os.write(buf, 0, readLen);
            }
            is.close();
            os.close();
            System.out.println("Extracted: " + ze.getName());
        }
        zfile.close();

    }

    /**
     * 给定根目录,返回一个相对路径所对应的实际文件名.
     *
     * @param baseDir     指定根目录
     * @param absFileName 相对路径名,来自于ZipEntry中的name
     * @return java.io.File 实际的文件
     */
    public static File getRealFileName(String baseDir, String absFileName) {
        String[] dirs = absFileName.split("/");
        // System.out.println(dirs.length);
        File ret = new File(baseDir);
        // System.out.println(ret);
        if (dirs.length > 1) {
            for (int i = 0; i < dirs.length - 1; i++) {
                ret = new File(ret, dirs[i]);
            }
        }
        if (!ret.exists()) {
            ret.mkdirs();
        }
        ret = new File(ret, dirs[dirs.length - 1]);
        return ret;
    }

这个方法在支持保存原有路径的基础上实现了不保留目录结构时重命名同名文件

import java.io.*;
import java.util.HashMap;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;


public class ZipUtils {

    private static HashMap<Object, Object> index = new HashMap<>();
    private static int count = 0;

    /**
     * 不保留目录结构时重命名同名文件:ZipUtils .zip
     * 压缩目标文件/夹, 存放于相同目录下(同级)
     * 最近整了一个压缩文件的工具类,功能:
     * 1、压缩文件夹,也可以压缩单独的文件
     * 2、压缩空文件夹(额..)
     * 3、目录结构是否保留可选
     * 4、压缩复杂文件夹(文件夹中带有文件夹)
     * 5、不保留目录结构时重命名同名文件
     * 压缩指定文件夹到指定目录下命名 不保留目录结构
     * zip("C:\\Users\\h2\\zipfile.zip", "C:\\Users\\h2h", false);
     * 压缩指定文件夹到指定目录下命名 保留目录结构
     * zip("C:\\Users\\gg\\zipfile.zip", "C:\\Users\\rio\\h2h", true);
     * 压缩指定文件到指定目录下命名
     * zip("C:\\Users\\h2\\gg\\zipfile.zip", "C:\\Users\\h1h\\a.txt", false);
     *
     * @param compressedFileName 压缩后的文件路径+压缩文件名
     * @param filePath           需要压缩的文件(夹)路径
     * @param keepStructure      是否保留目录结构
     * @return 压缩后的文件对象
     * @throws IOException 压缩异常
     */
    public static File zip(String compressedFileName, String filePath, boolean keepStructure) throws IOException {
        return zip(compressedFileName, new File(filePath), keepStructure);
    }

    /**
     * 压缩目标文件/夹, 存放于相同目录下(同级)
     *
     * @param compressedFileName 压缩后的文件名
     * @param file               需要压缩的文件
     * @param keepStructure      是否保留目录结构
     * @return 压缩后的文件对象
     * @throws IOException 压缩异常
     */
    public static File zip(String compressedFileName, File file, boolean keepStructure) throws IOException {
        if (file == null || !file.exists()) {
            return null;
        }
        /*if (isEmpty(compressedFileName)) {
            compressedFileName = file.getName();
        }*/

        // 维护一个目录
        if (keepStructure) {
            count = 0;
            index = new HashMap<>(10);
        }
        // 定义压缩文件名称
//        File zipFile = new File(file.getParentFile().getAbsolutePath() + File.separator + compressedFileName);
        File zipFile = new File(compressedFileName);
        if (!zipFile.getParentFile().exists()) {
            zipFile.getParentFile().mkdirs();
        }
        // 压缩流对象
        ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFile));
        // 文件直接压缩,文件夹递归压缩
        if (!file.isDirectory()) {
            addCompressedFile(zipOut, null, file);
        } else {
            addCompressedFloder(zipOut, null, file, keepStructure);
        }
        zipOut.close();
        System.out.println("压缩完成");
        return zipFile;
    }

    /**
     * 压缩文件夹
     *
     * @param zipOut        压缩流
     * @param parentPath    压缩文件路径
     * @param file          文件夹
     * @param keepStructure 是否保留目录结构
     */
    private static void addCompressedFloder(ZipOutputStream zipOut, String parentPath, File file, boolean keepStructure) throws IOException {
        if (file == null || !file.exists()) {
            return;
        }
        parentPath = empty(parentPath);
        if (!file.isDirectory()) {
            if (keepStructure) {
                addCompressedFile(zipOut, parentPath, file);
            } else {
                addCompressedFile(zipOut, null, file);
            }
        } else {
            //   System.out.println("读取目标文件夹" + file.getName());
            File[] files = file.listFiles();
            assert files != null;
            // 生成空文件夹
            if (keepStructure) {
                zipOut.putNextEntry(new ZipEntry(parentPath + file.getName() + File.separator));
            }
            for (File openFile : files) {
                addCompressedFloder(zipOut, parentPath + file.getName() + File.separator, openFile, keepStructure);
            }
        }
    }

    /**
     * 压缩文件
     *
     * @param zipOut     压缩流
     * @param parentPath 压缩文件目录
     * @param file       文件夹
     * @throws IOException
     */
    private static void addCompressedFile(ZipOutputStream zipOut, String parentPath, File file) throws IOException {
        InputStream input = new FileInputStream(file);
        String fileName = file.getName();
//        System.out.print("压缩目标文件" + fileName);
        if (parentPath != null) {
//            System.out.println(" 目录:" + parentPath + fileName);
            zipOut.putNextEntry(new ZipEntry(parentPath + fileName));
        } else {
//            System.out.println(" 目录:" + fileName);
            if (index.containsKey(fileName)) {
                String endType = "";
                String prefixName = "";
                if (fileName.contains(".")) {
                    endType = fileName.substring(fileName.lastIndexOf("."));
                    prefixName = fileName.substring(0, fileName.lastIndexOf("."));
                    count++;
                    zipOut.putNextEntry(new ZipEntry(prefixName + "(" + count + ")" + endType));
                    index.put(prefixName + "(" + count + ")" + endType, true);
                } else {
                    count++;
                    zipOut.putNextEntry(new ZipEntry("(" + count + ")" + fileName));
                    index.put("(" + count + ")" + fileName, true);
                }

            } else {
                zipOut.putNextEntry(new ZipEntry(fileName));
                index.put(fileName, true);
            }

        }
        int temp;
        while ((temp = input.read()) != -1) {
            zipOut.write(temp);
        }
        zipOut.closeEntry();
        input.close();
    }

    private static String empty(String s) {
        if (isEmpty(s)) {
            return "";
        }
        return s;
    }

    private static boolean isEmpty(String str) {
        return str == null || "".equals(str.trim());
    }

}

实现复制多个文件(夹)到指定目录下如果重名则重命名:copyFileOrDir
即可实现把不同路径下的文件或目录压缩到同一个文件夹下

import org.apache.commons.io.FileUtils;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class FileUtil {
    public static void main(String[] args) {
        List<File> fileList = new ArrayList<>();
        fileList.add(new File("C:\\Users\\Desktop\\ribao\\h2h"));
        fileList.add(new File("C:\\Users\\Desktop\\ribao\\h2\\h2h"));
        fileList.add(new File("C:\\Users\\Desktop\\ribao\\rr"));
        fileList.add(new File("C:\\Users\\Desktop\\ribao\\test2\\rr"));
        fileList.add(new File("C:\\Users\\Desktop\\ribao\\h2h\\b.txt"));
        fileList.add(new File("C:\\Users\\Desktop\\ribao\\h2h\\c.txt"));
        fileList.add(new File("C:\\Users\\Desktop\\ribao\\h2\\h2h\\b.txt"));
        copyFileOrDir(fileList, "C:\\Users\\Desktop\\ribao\\target");
    }

    /**
     * 实现复制多个文件(夹)到指定目录下如果重名则重命名:copyFileOrDir
     * 这块功能需求是:把不同路径下的文件或目录压缩到同一个文件夹下
     * 个人思路:把多个文件或文件夹放到同一个目标目录下在进行压缩
     * 由于放在一个目录下,我这里是循环,如果文件(夹)名相同就会后来的覆盖前面的问题
     * 因此需要通过重命名来防止文件重名造成的问题。
     * copyFileOrDir(fileList, "C:\\Users\\Desktop\\target");
     *
     * @param srcFiles
     * @param targetAbsolutePath
     * @throws RuntimeException
     */
    public static void copyFileOrDir(List<File> srcFiles, String targetAbsolutePath) {
        int i = 0;
        for (File srcFile : srcFiles) {
            ++i;
            ArrayList<File> filesAll = getDirAllFile(targetAbsolutePath, false);

            if (null == filesAll || filesAll.size() <= 0) {//如果目标目录下没有文件肯定不会重名
                if (srcFile.isFile()) {
                    String dirPath = targetAbsolutePath.endsWith(File.separator) ? targetAbsolutePath : targetAbsolutePath + File.separator;
                    copyFile(srcFile.getAbsolutePath(), dirPath + srcFile.getName());
                } else {
                    String dirPath = targetAbsolutePath.endsWith(File.separator) ? targetAbsolutePath : targetAbsolutePath + File.separator;
                    copyFilesCope(srcFile.getAbsolutePath(), dirPath + srcFile.getName());
                }
            } else {      //是否为重名文件(夹)
                if (duplicateName(filesAll, srcFile)) {//是
                    if (srcFile.isFile()) {
                        String newFileName = getNewName(srcFile.getAbsolutePath(), i);
                        String filePath = targetAbsolutePath.endsWith(File.separator) ? targetAbsolutePath : targetAbsolutePath + File.separator;
                        copyFile(srcFile.getAbsolutePath(), filePath + newFileName);
                    } else {
                        String newDirName = getNewName(srcFile.getAbsolutePath(), i);
                        String dirPath = targetAbsolutePath.endsWith(File.separator) ? targetAbsolutePath : targetAbsolutePath + File.separator;
//                        copyFilesCope(srcFile.getAbsolutePath(), temAbsolutePath);
                        copyFilesCope(srcFile.getAbsolutePath(), dirPath + newDirName);
                        //  deleteDirectoryAll(temAbsolutePath);
                    }
                } else {//不重名直接复制
                    if (srcFile.isFile()) {
                        String filePath = targetAbsolutePath.endsWith(File.separator) ? targetAbsolutePath : targetAbsolutePath + File.separator;
                        copyFile(srcFile.getAbsolutePath(), filePath + srcFile.getName());
                    } else {
                        String dirPath = targetAbsolutePath.endsWith(File.separator) ? targetAbsolutePath : targetAbsolutePath + File.separator;
                        copyFilesCope(srcFile.getAbsolutePath(), dirPath + srcFile.getName());
                    }
                }
            }
        }
    }

    //重名后的新的起名名称:getNewName
    public static String getNewName(String oldAbsolutePath, int no) {
        File file = new File(oldAbsolutePath);
        if (file.isFile()) {
            String name = file.getName();
            String type = "." + getFileNameOrType(name, "2");
            name = getFileNameOrType(name, "1");
            name = name + "(" + (no) + ")";
            return name + type;
        }
        if (file.isDirectory()) {
            String name = file.getName();
            name = name + "(" + (no) + ")";
            return name;
        }
        return null;
    }

    /**
     * 获取文件名称前缀与后缀:getFileNameOrType
     * getFileNameOrType("ab.c.ds.pdf", "1") ===>ab.c.ds     pdf
     *
     * @param fileName
     * @param flag
     * @return
     */
    public static String getFileNameOrType(String fileName, String flag) {
        if ("1".equals(flag)) {
            return fileName.substring(0, fileName.lastIndexOf("."));
        }
        return fileName.substring(fileName.lastIndexOf(".") + 1);
    }

    //检查是否有重名 :duplicateName
    public static boolean duplicateName(List<File> list, String targetFilePath) {
        File targetFile = new File(targetFilePath);
        for (File file : list) {
            if (file.getName().equals(targetFile.getName())) {
                return true;
            }
        }
        return false;
    }
    //检查是否有重名 :duplicateName
    public static boolean duplicateName(List<File> list, File targetFilePath) {
        for (File file : list) {
            if (file.getName().equals(targetFilePath.getName())) {
                return true;
            }
        }
        return false;
    }

    /**
     * 获取目录下的文件(夹)getDirAllFile
     *
     * @param path
     * @param childrenDir 是否包含子目录
     * @return
     */
    public static ArrayList<File> getDirAllFile(String path, boolean childrenDir) {
        ArrayList<File> files = new ArrayList<File>();
        File file = new File(path);
        File[] tempList = file.listFiles();
        if (null == tempList || tempList.length == 0) {
            return null;
        }
        for (int i = 0; i < tempList.length; i++) {
            files.add(tempList[i]);//把文件跟文件夹都放进来
            if (childrenDir) {//是否遍历子文件夹
                if (tempList[i].isDirectory()) {
                    ArrayList<File> files1 = getDirAllFile(tempList[i].getPath(), childrenDir);
                    files.addAll(files1);
                }
            }
        }
        return files;
    }

    /**
     * 复制文件 copyFile 跟上面 copyFileToWriteFile效果一致
     */
    public static boolean copyFile(String sourceFile, String targetFile) {
        File srcfile = new File(sourceFile);
        File destfile = new File(targetFile);

        try {
            FileUtils.copyFile(srcfile, destfile);
        } catch (IOException e) {
            System.out.println("复制文件[" + sourceFile + "]到指定位置[" + targetFile + "]时出错,请检查!");
            return false;
        } finally {
            if (null != srcfile) {
                srcfile = null;
            }
            if (null != destfile) {
                destfile = null;
            }
        }
        return true;
    }

    /**
     * 把文件夹下所有内容复制到指定文件夹下:copyFilesCope
     * copyFilesCope("C:\\Users\\h1h", "C:\\Users\\h2h\\cc");
     * 会把h1h文件下所有的内容 复制到cc文件夹下
     *
     * @param srcPath
     * @param targetPath
     */
    public static void copyFilesCope(String srcPath, String targetPath) {
        File src = new File(srcPath); //源文件夹
        File desc = new File(targetPath); //目标文件夹
        if (!desc.exists()) { //如果目标文件夹不存在
            desc.mkdirs(); //创建目标文件夹
        }
        long start = System.currentTimeMillis();
        try {
            copyFilesCope(src, desc); //复制文件夹
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void copyFilesCope(File src, File desc) throws IOException {
        if (src.isFile()) { //如果是文件
            FileInputStream fis = new FileInputStream(src);
            String path = desc.getAbsolutePath();
            FileOutputStream fos = new FileOutputStream(path);
            BufferedInputStream bis = new BufferedInputStream(fis);
            BufferedOutputStream bos = new BufferedOutputStream(fos);
            byte[] b = new byte[1024 * 1024];
            int len = 0;
            while ((len = bis.read(b)) != -1) {
                bos.write(b, 0, len);
            }
            bos.flush();
            bos.close();
            bis.close();
        } else { //如果是文件夹
            File[] files = src.listFiles(); //获取文件夹下的所有文件
            if (files.length == 0) { //如果文件夹为空
                String srcPath = src.getName(); //获取文件夹名称
                //拿到新文件夹的路径,新文件夹的路径为:目标文件夹的路径+文件夹名称
                String descPath = (desc.getAbsolutePath().endsWith("\\") ? desc.getAbsolutePath() : desc.getAbsolutePath() + "\\" + srcPath);
                File newFile = new File(descPath); //创建新文件夹
                if (!newFile.exists()) { //如果新文件夹不存在
                    newFile.mkdirs(); //创建新文件夹
                }
            } else { //如果文件夹不为空
                for (File f : files) { //遍历文件夹下的所有文件
                    String srcPath = f.getName(); //获取文件或文件夹的名称
                    String descPath = ""; //新文件夹的路径
                    if (f.isFile()) { //如果是文件
                        descPath = desc.getAbsolutePath() + "\\" + f.getName(); //新文件夹的路径为:目标文件夹的路径+文件夹名称
                    }
                    if (f.isDirectory()) { //如果是文件夹
                        //拿到新文件夹的路径,新文件夹的路径为:目标文件夹的路径+文件夹名称
                        descPath = (desc.getAbsolutePath().endsWith("\\") ? desc.getAbsolutePath() : desc.getAbsolutePath() + "\\" + srcPath);
                    }
                    File newFile = new File(descPath); //创建新文件夹
                    if (f.isDirectory()) { //如果是文件夹
                        if (!newFile.exists()) { //如果新文件夹不存在
                            newFile.mkdirs(); //创建新文件夹
                        }
                    }
                    copyFilesCope(f, newFile); //递归调用,此时拿到的newFile为目标路径,f为源路径
                }
            }
        }
    }

}

rename
业务场景:前端上传多个文件,如果文件重名则需要重命名
说白了这个就是处理集合中某属性的重复名称进行重命名

import lombok.Data;

@Data
public class BatchDownloadDto {
    private String downloadId;
    private String fileName;

    public BatchDownloadDto() {
    }

    public BatchDownloadDto(String downloadId, String fileName) {
        this.downloadId = downloadId;
        this.fileName = fileName;
    }
}

这块我改版了3个实现模式,项目中我用的是rename、但是我推荐rename2

package org.example.demo.onetest.history.work.dd;

import java.util.*;
import java.util.stream.Collectors;

public class FileRenameMethod {
    public static void main(String[] args) {
        List<BatchDownloadDto> list = new ArrayList<>();
        list.add(new BatchDownloadDto("1", "a.pdf"));
        list.add(new BatchDownloadDto("2", "a.pdf"));
        list.add(new BatchDownloadDto("3", "a.pdf"));
        list.add(new BatchDownloadDto("4", "b.pdf"));
        list.add(new BatchDownloadDto("5", "c.pdf"));
        list.add(new BatchDownloadDto("6", "b.pdf"));
        list.add(new BatchDownloadDto("7", "a.pdf"));
        list.add(new BatchDownloadDto("8", "a.pdf"));


        rename(list).stream().forEach(p -> {
            System.out.print(p.getFileName() + ",");
        });
        System.out.println("\n" + "======================");
//        rename2(list).stream().forEach(p -> {
//            System.out.print(p.getFileName() + ",");
//        });

        rename1(list).stream().forEach(p -> {
            System.out.print(p.getFileName() + ",");
        });
        System.out.println("----------");

        List<BatchDownloadDto> batchDownloadDtos = rename1(list);
        for (BatchDownloadDto batchDownloadDto : batchDownloadDtos) {
            System.out.println(batchDownloadDto.getFileName());
        }
    }

    //注意这个方法的话数据的顺序会跟原来数据顺序不一致
    public static List<BatchDownloadDto> rename2(List<BatchDownloadDto> list) {
        List<BatchDownloadDto> newBatchDownloadDto = new ArrayList<>();
        Map<String, List<BatchDownloadDto>> mapFileNames = list.stream().collect(Collectors.groupingBy(BatchDownloadDto::getFileName));
        Set<String> setFileName = list.stream().map(BatchDownloadDto::getFileName).collect(Collectors.toSet());
        for (String filename : setFileName) {
            List<BatchDownloadDto> batchDownloadDtos = mapFileNames.get(filename);
            for (int i = 0; i < batchDownloadDtos.size(); i++) {
                BatchDownloadDto downloadDto = batchDownloadDtos.get(i);
                if (i == 0) {
                    newBatchDownloadDto.add(downloadDto);
                    continue;
                }
                String fileName = downloadDto.getFileName();
                String startName = fileName.substring(0, fileName.lastIndexOf("."));
                String endName = fileName.substring(fileName.lastIndexOf("."));
                downloadDto.setFileName(startName + "(" + i + ")" + endName);
                newBatchDownloadDto.add(downloadDto);
            }
        }

        return newBatchDownloadDto;
    }

    public static List<BatchDownloadDto> rename(List<BatchDownloadDto> list) {
        List<BatchDownloadDto> batchDownloadDtos = new ArrayList<>();
        for (BatchDownloadDto batchDownloadDto : list)
            if (!duplicateName(batchDownloadDtos, batchDownloadDto.getFileName())) {
                batchDownloadDtos.add(batchDownloadDto);//设有重名
            } else {//有重名
                String fileName = batchDownloadDto.getFileName();
                int i = 0;
                String newFileName;
                do {
                    i++;//如果重复就重命名增加编号
                    newFileName = fileName.substring(0, fileName.lastIndexOf(".")) +
                            "(" + i + ")" + fileName.substring(fileName.lastIndexOf("."), fileName.length());
                } while (duplicateName(batchDownloadDtos, newFileName));
                batchDownloadDto.setFileName(newFileName);
                batchDownloadDtos.add(batchDownloadDto);

            }
        return batchDownloadDtos;
    }

    public static List<BatchDownloadDto> rename1(List<BatchDownloadDto> list) {
        List<BatchDownloadDto> batchDownloadDtos = new ArrayList<>();
        Set set = new HashSet();
        for (BatchDownloadDto batchDownloadDto : list) {
            int beforeSize = set.size();
            set.add(batchDownloadDto.getFileName());
            int nowSize = set.size();
            if (nowSize > beforeSize) {
                batchDownloadDtos.add(batchDownloadDto);//设有重名
            } else {//有重名
                String fileName = batchDownloadDto.getFileName();
                int i = 0;
                String newFileName;
                do {
                    beforeSize = set.size();
                    i++;//如果重复就重命名增加编号
                    newFileName = fileName.substring(0, fileName.lastIndexOf(".")) +
                            "(" + i + ")" + fileName.substring(fileName.lastIndexOf("."), fileName.length());
                    set.add(newFileName);
                    nowSize = set.size();
                    if (nowSize != beforeSize){
                        break;
                    }
                } while (nowSize >= beforeSize);
                batchDownloadDto.setFileName(newFileName);
                batchDownloadDtos.add(batchDownloadDto);
            }


        }
        return batchDownloadDtos;
    }

    public static boolean duplicateName(List<BatchDownloadDto> list, String fileName) {
        for (BatchDownloadDto batchDownloadDto : list) {
            if (batchDownloadDto.getFileName().equals(fileName)) {
                return true;
            }
        }
        return false;
    }
}