文件操作工具类

import cn.hutool.core.collection.CollectionUtil;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
 
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
 
/**
 * @description
 **/
public class FileUtil {
    
    /***
     * @Description:将文件路径统一转换成”C:/Users/Daasan/Desktop“格式
     * @data:[filePath]
     * @return: java.lang.String
     */
    public static String formatPath(String filePath) {
        if (StringUtils.isEmpty(filePath)){
            return "";
        }
        // 将反斜杠转为正斜杠
        filePath = filePath.replaceAll("\\\\", "/");
        // 将连续的斜杠替换为单个斜杠
        filePath = filePath.replaceAll("/{2,}", "/");
        // 如果路径以斜杠结尾,则去掉结尾的斜杠
        if (filePath.endsWith("/")) {
            filePath = filePath.substring(0, filePath.length() - 1);
        }
        return filePath;
    }
 
    /**
     **获取文件路径中的最后一级(目录或文件名称)
     * \aa\bb\cc\dd  -->  dd
     * \aa\bb\cc\dd.txt  -->  dd.txt
     * @param filePath
     * @return java.lang.String
     **/
    public static String getPathLastLevel(String filePath) {
        //判空
        if (StringUtils.isEmpty(filePath)){
            return "";
        }
        // 格式化文件路径
        filePath = formatPath(filePath);
 
        int index = filePath.lastIndexOf("/");
        if (index != -1) {
            return filePath.substring(index + 1);
        }
        return filePath;
    }
 
    /**
     **获取文件的后缀:  test.ppt  -->  ppt
     * @param fileName 文件名称
     * @return java.lang.String
     **/
    public static String getFileSuffix(String fileName) {
        if (fileName == null) {
            return null;
        }
        int index = fileName.lastIndexOf(".");
        if (index == -1) {
            return "";
        }
        return fileName.substring(index + 1);//不包含”.“
    }
 
    /**
     **获取文件的名称(去掉后缀)
     * @param fileName
     * @return java.lang.String
     **/
    public static String getFileNameWithoutSuffix(String fileName) {
        if (fileName == null) {
            return null;
        }
        int index = fileName.lastIndexOf(".");
        if (index == -1) {
            return fileName;
        }
        return fileName.substring(0, index);
    }
 
    /**
     **创建空文件
     * @param file 需创建的文件
     * @return void
     **/
    public static void createEmptyFile(File file) throws IOException {
        if (file.exists()) {
            return;
        }
        File parent = file.getParentFile();
        if (parent != null && !parent.exists()) {
            parent.mkdirs();
        }
        file.createNewFile();
    }
 
    /**
     **批量移动磁盘中的文件
     * @param rootPath 根目录
     * @param absolutePathList 存放源文件和目标文件的绝对路径
     * @return void
     **/
    public static void moveFiles(String rootPath, List<Map<String, String>> absolutePathList) throws IOException {
        for (Map<String, String> pathMap : absolutePathList) {
            String oldFilePath = pathMap.get("oldFilePath");
            String newFilePath = pathMap.get("newFilePath");
            Path sourcePath = Paths.get(formatPath(rootPath + oldFilePath));
            Path targetPath = Paths.get(formatPath(rootPath + newFilePath));
            Files.move(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
        }
    }
 
    /**
     **从网络路径中获取文件的字节数组
     * @param urlStr 文件的网络路径
     * @return byte[] 文件的字节数组
     **/
    public static byte[] getByteFromUrl(String urlStr) throws IOException {
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpGet httpGet = new HttpGet(urlStr);
            try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
                return EntityUtils.toByteArray(response.getEntity());
            }
        }
    }
 
    /**
     **递归获取文件夹下的所有文件和文件夹
     * @param folder
     * @return java.util.List<java.io.File>
     **/
    public static List<File> getFilesRecursively(File folder) {
        List<File> fileList = new ArrayList<>();
        File[] files = folder.listFiles();
        if (files != null) {
            for (File file : files) {
                fileList.add(file);
                if (file.isDirectory()) {
                    fileList.addAll(getFilesRecursively(file));
                }
            }
        }
        return fileList;
    }
 
    /**
     **去掉路径中的特殊字符
     * @param path
     * @return java.nio.file.Path
     **/
    public static Path sanitizePath(Path path) {
 
        String fileName = path.getFileName().toString();
        String parentPathString = path.getParent().toString();
 
        // 定义特殊字符的正则表达式
        Pattern pattern = Pattern.compile("[\\\\/:*?\"<>|&'+-=]");
 
        // 使用空字符串替换特殊字符
        String sanitizedFileName = pattern.matcher(fileName).replaceAll("");
 
        Path path1 = Paths.get(parentPathString, sanitizedFileName);
 
        // 返回路径的父路径与处理后的文件名拼接成的完整路径
        return path1;
    }
 
    /**
     **判断文件名称中是否包含特殊字符
     * @param fileName
     * @return boolean
     **/
    public static boolean hasSpecialCharacters(String fileName) {
        String SPECIAL_CHARACTERS_REGEX = "[!@#$%^&*()_+\\-=\\[\\]{};':\"\\\\|,<>\\/?]";
        Pattern pattern = Pattern.compile(SPECIAL_CHARACTERS_REGEX);
        return pattern.matcher(fileName).find();
    }
 
    /**
     **去掉文件名称中包含的特殊字符
     * @param fileName
     * @return java.lang.String
     **/
    public static String removeSpecialCharacters(String fileName) {
        String SPECIAL_CHARACTERS_REGEX = "[!@#$%^&*()_+\\-=\\[\\]{};':\"\\\\|,<>\\/?]";
        return fileName.replaceAll(SPECIAL_CHARACTERS_REGEX, "");
    }
 
    /**
     * 获取文件的绝对路径
     * 
     * @param filePath 文件路径
     * @return 文件的绝对路径
     */
    public static String getAbsolutePath(String filePath) {
        File file = new File(filePath);
        return file.getAbsolutePath();
    }
 
 
    /**
     * 复制文件
     * 
     * @param sourceFilePath      源文件路径
     * @param destinationFilePath 目标文件路径
     * @throws IOException 如果复制过程中出现错误,抛出 IOException
     */
    public static void copyFile(String sourceFilePath, String destinationFilePath) throws IOException {
        File sourceFile = new File(sourceFilePath);
        File destinationFile = new File(destinationFilePath);
        
        if (!sourceFile.exists()) {
            throw new FileNotFoundException("Source file does not exist: " + sourceFilePath);
        }
        
        try (InputStream inputStream = new FileInputStream(sourceFile);
             OutputStream outputStream = new FileOutputStream(destinationFile)) {
            byte[] buffer = new byte[4096];
            int length;
            while ((length = inputStream.read(buffer)) > 0) {
                outputStream.write(buffer, 0, length);
            }
        }
    }
 
    /**
     **修改文件的名称
     * @param filePath
     * @param newFileName
     * @return void
     **/
    public static void renameFile(String filePath, String newFileName) {
        File file = new File(filePath);
        if (file.exists()) {
            String parentPath = file.getParent();
            String newFilePath = parentPath + File.separator + newFileName;
            File newFile = new File(newFilePath);
            if (file.renameTo(newFile)) {
                System.out.println("文件重命名成功!");
            } else {
                System.out.println("文件重命名失败!");
            }
        } else {
            System.out.println("文件不存在!");
        }
    }
 
    /**
     **递归获取文件夹下所有文件的路径后,将路径放到filePaths中
     * @param folderPath 文件夹路径
     * @param filePaths 存放文件路径的集合
     * @return void
     **/
    public static void getAllFilePaths(String folderPath, List<String> filePaths) {
        File folder = new File(folderPath);
        // 获取文件夹下所有文件和子文件夹
        File[] files = folder.listFiles();
 
        if (files != null) {
            for (File file : files) {
                if (file.isFile()) {
                    // 如果是文件,将文件路径添加到列表中
                    filePaths.add(file.getAbsolutePath());
                } else if (file.isDirectory()) {
                    // 如果是文件夹,则递归调用该方法获取文件夹下所有文件路径
                    getAllFilePaths(file.getPath(), filePaths);
                }
            }
        }
    }
 
    /**
     **将源文件夹下的所有文件复制到目标文件夹下
     * @param sourceFolderPath
     * @param targetFolderPath
     * @return void
     * @author yinqi
     * @create 2024/3/25 11:41
     **/
    public static void copyFolder(String sourceFolderPath, String targetFolderPath) throws IOException {
        File sourceFolder = new File(sourceFolderPath);
        File targetFolder = new File(targetFolderPath);
 
        // 检查源文件夹是否存在
        if (!sourceFolder.exists()) {
            throw new IllegalArgumentException("源文件夹不存在");
        }
 
        // 检查目标文件夹是否存在,如果不存在则创建
        if (!targetFolder.exists()) {
            targetFolder.mkdirs();
        }
 
        // 获取源文件夹下的所有文件和文件夹
        File[] files = sourceFolder.listFiles();
 
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    // 如果是文件夹,则递归调用copyFolder方法复制文件夹
                    copyFolder(file.getAbsolutePath(), targetFolderPath + File.separator + file.getName());
                } else {
                    // 如果是文件,则使用Files.copy方法复制文件
                    Path sourcePath = file.toPath();
                    Path targetPath = new File(targetFolderPath + File.separator + file.getName()).toPath();
 
                    Files.copy(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
                }
            }
        }
    }
}