LocalFileUtils.java 13.3 KB
package com.irrigation.icl.utils;


import com.irrigation.icl.exception.ContextRuntimeException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
import java.util.Optional;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

/**
 * @description:
 * @Author: yangLang
 * @CreateDate: 2020/9/2 14:39
 */
@Slf4j
public class LocalFileUtils {


    /**
     * 文件后缀分隔符
     */
    public static final String FILE_SUFFIX_SEPARATOR = ".";

    /**
     * 编码方式
     */
    public final static String DEFAULT_CHARSET = "GBK";

    private LocalFileUtils() {
    }

    /**
     * 创建文件
     *
     * @param parentFile 辅机目录
     * @param fileName   文件名称
     * @return java.io.File
     * @Author yangLang
     * @Date 15:30 2020/9/2
     */
    public static File getFile(File parentFile, String fileName) {
        Assert.notNull(fileName, "Depending create file is null");
        File file;
        if (ObjectUtils.isNull(parentFile)) {
            file = new File(fileName);
        } else {
            file = new File(parentFile, fileName);
        }
        if (!file.exists()) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                log.error("Create File Failed:{}", e.getMessage());
            }
        }
        Assert.isTrue(file.exists(), "Create file failed");
        return file;
    }

    /**
     * 创建目录
     *
     * @param parentFile 父目录
     * @param filePath   目录的指定路径
     * @return java.io.File
     * @Author yangLang
     * @Date 15:22 2020/9/2
     */
    public static File getDirectoryFile(File parentFile, String filePath) {
        Assert.notNull(filePath, "Depending created file is null");
        File file;
        if (ObjectUtils.isNull(parentFile)) {
            file = new File(filePath);
        } else {
            file = new File(parentFile, filePath);
        }
        if (!file.exists()) {
            file.mkdirs();
        }
        Assert.isTrue(file.exists(), "Created file failed");
        return file;
    }

    /**
     * 获取文件的后缀名
     *
     * @param file                     文件名
     * @param isContainSuffixSeparator 是否包含文件后缀分隔符
     * @return java.lang.String
     * @Author yangLang
     * @Date 16:01 2020/9/2
     */
    public static String getFileExtension(File file, boolean isContainSuffixSeparator) {
        Assert.notNull(file, "File is null");
        String fileName = file.getName();
        Assert.notNull(fileName, "File is not exist");
        int index = fileName.lastIndexOf(FILE_SUFFIX_SEPARATOR);
        if (index == -1 || index >= fileName.length()) {
            return null;
        }
        if (!isContainSuffixSeparator) {
            index++;
        }
        return fileName.substring(index);
    }

    /**
     * 获取文件的后缀名
     *
     * @param filePath                 文件路径
     * @param isContainSuffixSeparator 是否包含文件后缀分隔符
     * @return java.lang.String
     * @Author yangLang
     * @Date 16:02 2020/9/2
     */
    public static String getFilePathExtension(String filePath, boolean isContainSuffixSeparator) {
        Assert.notNull(filePath, "File is null");
        int index = filePath.lastIndexOf(FILE_SUFFIX_SEPARATOR);
        if (index == -1 || index >= filePath.length()) {
            return null;
        }
        if (!isContainSuffixSeparator) {
            index++;
        }
        return filePath.substring(index);
    }

    /**
     * 获取 MultipartFile 文件后缀
     *
     * @param file                     文件
     * @param isContainSuffixSeparator 是否包含文件后缀分隔符
     * @return java.lang.String 后缀字符串
     * @Author yangLang
     * @Date 9:39 2020/9/3
     */
    public static String getMultipartFileExtension(MultipartFile file, boolean isContainSuffixSeparator) {
        Assert.notNull(file, "File is null");
        int index = file.getOriginalFilename().lastIndexOf(FILE_SUFFIX_SEPARATOR);
        if (index == -1 || index >= file.getOriginalFilename().length()) {
            return null;
        }
        if (!isContainSuffixSeparator) {
            index++;
        }
        return file.getOriginalFilename().substring(index);
    }

    /**
     * 判断文件是否为期望的文件格式(不包含文件后缀分隔符)
     *
     * @param file            文件
     * @param expectExtension 期望的文件格式
     * @return boolean
     * @Author yangLang
     * @Date 16:17 2020/9/2
     */
    public static boolean judgeFileExtension(File file, String expectExtension) {
        Assert.notNull(file, "Depend judge file is null");
        Assert.notNull(expectExtension, "The expect extension is null");
        String fileExtension = getFileExtension(file, false);
        return expectExtension.equalsIgnoreCase(fileExtension);
    }

    /**
     * 判断文件路径是否为期望的文件格式(不包含文件后缀分隔符)
     *
     * @param filePath        文件路径
     * @param expectExtension 期望的文件格式
     * @return boolean
     * @Author yangLang
     * @Date 9:42 2020/9/3
     */
    public static boolean judgeFilePathExtension(String filePath, String expectExtension) {
        Assert.notNull(filePath, "Depend judge file is null");
        Assert.notNull(expectExtension, "The expect extension is null");
        String fileExtension = getFilePathExtension(filePath, false);
        return expectExtension.equalsIgnoreCase(fileExtension);
    }

    /**
     * 判断文件是否为期望的文件格式(不包含文件后缀分隔符)
     *
     * @param file            文件
     * @param expectExtension 期望的格式
     * @return boolean
     * @Author yangLang
     * @Date 16:19 2020/9/2
     */
    public static boolean judgeMultipartFileExtension(MultipartFile file, String expectExtension) {
        Assert.notNull(file, "Depend judge file is null");
        Assert.notNull(expectExtension, "The expect extension is null");
        String fileExtension = getFilePathExtension(file.getOriginalFilename(), false);
        return expectExtension.equalsIgnoreCase(fileExtension);
    }

    /**
     * multipartFile 转 File
     *
     * @param multipartFile 带转换的 multipartFile 文件
     * @param parentFile    转换完成后的文件所在的目录
     * @return java.io.File
     * @Author yangLang
     * @Date 17:03 2020/9/2
     */
    public static File multipartFile2File(MultipartFile multipartFile, File parentFile) {
        Assert.notNull(multipartFile, "Depend trances file is null");
        Assert.isTrue(parentFile.isDirectory(), "Parent File not a directory");
        File tempFile = getFile(parentFile, multipartFile.getOriginalFilename());
        try (InputStream inputStream = multipartFile.getInputStream()) {
            FileUtils.copyInputStreamToFile(inputStream, tempFile);
        } catch (IOException e) {
            throw new ContextRuntimeException("文件转换失败");
        }
        return tempFile;
    }

    /**
     * 解压文件到指定目录,解压后的文件名和之前一致
     *
     * @param unZipFile       解压文件
     * @param parentFile      解压文件后所置的目录
     * @param encode          编码方式,默认是GBK
     * @param isDeleteZipFile 是否需要删除压缩文件,默认不删除
     * @return void
     * @Author yangLang
     * @Date 17:14 2020/9/2
     */
    public static void unZipFile(File unZipFile, File parentFile, String encode, Boolean isDeleteZipFile) {
        Assert.notNull(parentFile, "Unzip file's parent file is null");
        try (ZipFile zip = new ZipFile(unZipFile, Charset.forName(Optional.ofNullable(encode).orElse(DEFAULT_CHARSET)))) {
            FileOutputStream out = null;
            for (Enumeration<? extends ZipEntry> entries = zip.entries(); entries.hasMoreElements(); ) {
                ZipEntry entry = entries.nextElement();
                String zipEntryName = entry.getName();
                try (InputStream in = zip.getInputStream(entry)) {
                    int index = zipEntryName.lastIndexOf(StringUtils.cleanPath(File.separator));
                    File file;
                    // 如果是文件夹,只创建文件夹,直接返回,无需读写文件
                    if (index == zipEntryName.length() - 1 || index == -1) {
                        getDirectoryFile(parentFile, zipEntryName);
                        continue;
                    } else {
                        // 获取文件的名称
                        String substring = zipEntryName.substring(0, index);
                        // 创建父文件目录
                        file = getDirectoryFile(parentFile, substring);
                        // 创建文件
                        file = getFile(file, zipEntryName.substring(index + 1));
                    }
                    out = new FileOutputStream(file);
                    byte[] buf1 = new byte[1024];
                    int len;
                    while ((len = in.read(buf1)) > 0) {
                        out.write(buf1, 0, len);
                    }
                } finally {
                    if (out != null) {
                        out.flush();
                        out.close();
                    }
                }
            }
        } catch (IOException e) {
            throw new ContextRuntimeException("File = " + unZipFile.getName() + " unzip failed.");
        }
        if (Optional.ofNullable(isDeleteZipFile).orElse(Boolean.FALSE)) {
            FileUtils.deleteQuietly(unZipFile);
        }
    }

    /**
     * 压缩文件
     *
     * @param zipFiles            待压缩的文件
     * @param parentFile          压缩完成的文件所在目录
     * @param isDeleteSourcesFile 是否需要删除压缩前的源文件
     * @param zipFileName         压缩完成后的文件名称
     * @return java.io.File 压缩完成的文件
     * @Author yangLang
     * @Date 17:10 2020/9/2
     */
    public static File zipFile(List<File> zipFiles, File parentFile, String zipFileName, Boolean isDeleteSourcesFile) {
        Assert.isTrue(ObjectUtils.nonEmpty(zipFiles), "Depending compress file is null");
        Assert.notNull(zipFileName, "Compress file name is null");
        Assert.notNull(parentFile, "Parent file of unzip file is null");
        File newFile = getFile(parentFile, zipFileName);
        Assert.notNull(newFile, "Zip file create failed");
        try (FileOutputStream fos = new FileOutputStream(newFile);
             ZipOutputStream zos = new ZipOutputStream(fos)) {
            zipFiles.stream().forEach(item -> writeZip(item, "", zos));
        } catch (IOException e) {
            log.error("Failed to create compressed file:{}", e.getMessage());
        }
        if (Optional.ofNullable(isDeleteSourcesFile).orElse(Boolean.FALSE)) {
            zipFiles.stream().forEach(item -> {
                try {
                    FileUtils.deleteDirectory(item);
                } catch (IOException e) {
                    log.error("File = {} delete failed", item.getAbsolutePath());
                }
            });
        }
        return newFile;
    }

    /**
     * 写压缩文件
     *
     * @param file       待压缩的文件夹
     * @param parentPath 父文件路径
     * @param zos        压缩流
     * @return void
     * @Author yangLang
     * @Date 16:21 2020/8/6
     */
    private static void writeZip(File file, String parentPath, ZipOutputStream zos) {
        if (!file.exists()) {
            log.error("File = {} does not exist", file.getAbsolutePath());
            return;
        }
        if (!file.isDirectory()) {
            zipWrite2File(file, parentPath, zos);
            return;
        }
        File[] subFiles = file.listFiles();
        String subParentPath = parentPath + file.getName() + File.separator;
        // 空目录则创建当前目录
        if (subFiles.length == 0) {
            try {
                zos.putNextEntry(new ZipEntry(subParentPath));
            } catch (IOException e) {
                log.warn("{} Folder is empty", subParentPath);
            }
            return;
        }
        // 如果目录下包含文件,则递归压缩子文件
        Arrays.stream(subFiles).forEach(item -> writeZip(item, subParentPath, zos));
    }

    /**
     * 压缩文件的时候写文件
     *
     * @param file       文件
     * @param parentPath 父目录
     * @param zos        压缩流
     * @return void
     * @Author yangLang
     * @Date 16:29 2020/8/6
     */
    private static void zipWrite2File(File file, String parentPath, ZipOutputStream zos) {
        ZipEntry ze = new ZipEntry(parentPath + file.getName());
        try (FileInputStream fis = new FileInputStream(file)) {
            zos.putNextEntry(ze);
            byte[] content = new byte[1024];
            int len;
            while ((len = fis.read(content)) != -1) {
                zos.write(content, 0, len);
                zos.flush();
            }
        } catch (Exception e) {
            log.error("Failed to compress file = {}:{}", file.getName(), e.getMessage());
        }
    }
}