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 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 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()); } } }