Zip压缩文件夹 + 前端导出

压缩本地文件成Zip,供前端导出

代码

JAVA 复制代码
/**
     * now 是当前时间戳
     * exportDir是导出目录路径 如D://export//111222333AA
     * @param response
     * @param now
     * @param exportDir
     */
    private void compressExportDirAndExport(HttpServletResponse response, long now, String exportDir) {
        //压缩导出目录exportDir
        String zipFilePath = exportDir + ".zip";
        File zipFileFile = new File(zipFilePath);
        if (!zipFileFile.exists()) {
            try {
                zipFileFile.createNewFile();
            } catch (IOException e) {
                log.error("{}",e);
            }
        }

        File exportDirFile = new File(exportDir);
        if (!exportDirFile.exists()) {
            exportDirFile.mkdirs();
        }

        FileUtil.compressDirectory(exportDirFile,zipFilePath,true);

        //返回给前端
        try {
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/zip");
            String fileName = zipFileFile.getName();
            response.setHeader("Content-Disposition", "attachment;FileName=" + fileName);
            ServletOutputStream out = response.getOutputStream();
            int len = 0;
            byte[] buffer = new byte[1024];
            FileInputStream fis = new FileInputStream(zipFileFile);
            while ((len = fis.read(buffer)) > 0) {
                out.write(buffer, 0, len);
                out.flush();
            }
            out.close();
            fis.close();
            response.flushBuffer();
        } catch (IOException e) {
            log.error("下载文件失败", e);
        }

        //删除导出目录文件夹
        FileUtil.deleteDirectory(exportDir);
        //删除压缩文件
        FileUtil.deleteFile(zipFilePath);
    }

FileUtil工具类

java 复制代码
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.PosixFilePermission;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;


/**
 * 文件工具类
 * FileUtils
 *
 * @author glj
 * @version 1.0, 2015-3-9
 */
@Slf4j
public class FileUtil {
    /**
     * 获取文件扩展名
     *
     * @param fileName 文件名称
     * @return
     */
    public static String getExtensionName(String fileName) {

        if ((fileName != null) && (fileName.length() > 0)) {

            int dot = fileName.lastIndexOf('.');
            if ((dot > -1) && (dot < (fileName.length() - 1))) {
                return fileName.substring(dot + 1);
            }
        }
        return fileName;
    }

    /**
     * 获取不带扩展名的文件名称
     *
     * @param fileName 文件名称
     * @return
     */
    public static String getFileNameNoExt(String fileName) {

        if ((fileName != null) && (fileName.length() > 0)) {

            int dot = fileName.lastIndexOf('.');
            if ((dot > -1) && (dot < (fileName.length()))) {
                return fileName.substring(0, dot);
            }
        }
        return fileName;
    }

    /**
     * 根据输入流来保存文件信息
     *
     * @param inputStream   文件输入流
     * @param localBasePath 目录
     * @param fileName      文件名称
     * @return 文件对象
     */
    public static File saveFileFromInputStream(InputStream inputStream, String localBasePath, String fileName) throws IOException {
        File dir = new File(localBasePath);
        if (!dir.exists()) {
            boolean dirs = dir.mkdirs();
        }
        File file = new File(localBasePath + File.separator + fileName);
        if (!file.exists()) {
            boolean newFile = file.createNewFile();
        }
        try (FileOutputStream fs = new FileOutputStream(file)) {
            byte[] buffer = new byte[1024 * 1024];
            int num;
            while ((num = inputStream.read(buffer)) != -1) {
                fs.write(buffer, 0, num);
                fs.flush();
            }
        } finally {
            inputStream.close();
        }
        return file;
    }

    /**
     * 上传文件
     *
     * @param stream   文件数据流
     * @param filePath 服务器上文件路径
     * @return
     * @throws IOException
     */
    public static boolean uploadFile(InputStream stream, String filePath) throws IOException {

        File file = new File(filePath);

        //验证所选路径是否存在,不存在,先创建路径
        String localBasePath = file.getParentFile().getPath();

        File dir = new File(localBasePath);

        if (!dir.exists()) {
            dir.mkdirs();
        }


        if (!file.exists()) {
            file.createNewFile();
        }

        FileOutputStream fs = new FileOutputStream(file);
        byte[] buffer = new byte[1024 * 1024];
        int byteread = 0;
        while ((byteread = stream.read(buffer)) != -1) {
            fs.write(buffer, 0, byteread);
            fs.flush();
        }
        fs.close();
        stream.close();


        if (file.exists()) {

            return true;

        } else {

            return false;
        }
    }

    /**
     * 删除文件
     *
     * @param filePath 文件路径
     * @return
     * @throws IOException
     */
    public static boolean removeFile(String filePath) throws IOException {
        File file = new File(filePath);
        //判断文件是否存在
        if (file.exists()) {
            //如果存在,则删除该文件
            return file.delete();

        } else {
            //文件不存在,则返回false
            return false;
        }
    }

    //删除非任务上传文件夹下面的数据
    public static void deleteFile(File oldPath) {
        if (oldPath.isDirectory()) {
            File[] files = oldPath.listFiles();
            for (File file : files) {
                deleteFile(file);
            }
            oldPath.delete();
        } else {
            oldPath.delete();
        }
    }

    /**
     * zipFile
     * 将指定文件进行ZIP格式压缩
     *
     * @param zipFilesPath 带压缩的文件路径列表
     * @param fileName     压缩成的目标文件路径
     * @return 返回压缩后的文件路径
     * @throws IOException 压缩过程中的IO异常
     */
    public static String zipFile(List<String> zipFilesPath, String fileName)
            throws IOException {
        ZipOutputStream zos = new ZipOutputStream(
                Files.newOutputStream(Paths.get(fileName)));
        ZipEntry ze = null;
        byte[] buf = new byte[1024];
        int readln = -1;
        for (int i = 0; i < zipFilesPath.size(); i++) {
            ze = new ZipEntry(zipFilesPath.get(i));
            ze.setSize(new File(zipFilesPath.get(i)).length());
            ze.setTime(new File(zipFilesPath.get(i)).lastModified());
            zos.putNextEntry(ze);
            InputStream is = new BufferedInputStream(Files.newInputStream(Paths.get(zipFilesPath.get(i))));

            while ((readln = is.read(buf, 0, 1024)) != -1) {
                zos.write(buf, 0, 1024);
            }
            is.close();

        }
        zos.close();
        return fileName;
    }

    /**
     * 复制文件到指定位置
     *
     * @param sourceFileFullPath 要复制的文件全路径 如D://test//test.txt
     * @param targetFileFullPath 复制到目标文件全路径 如D://move//test.txt
     * @return 是否复制成功, true:成功;否则失败
     */
    public static boolean copyFileToTarget(String sourceFileFullPath, String targetFileFullPath) {
        try {
            FileUtils.copyFile(new File(sourceFileFullPath), new File(targetFileFullPath));
            return true;
        } catch (IOException e) {
            log.error("copyFileToTarget={}", e.getMessage());
        }
        return false;
    }

    /**
     * 复制文件夹到指定位置
     *
     * @param sourceFileFullPath 要复制的文件全路径
     * @param targetFileFullPath 复制到目标位置的目录全路径
     * @return 是否复制成功, true:成功;否则失败
     */
    public static boolean copyDirectoryToTarget(String sourceFileFullPath, String targetFileFullPath) {
        try {
            FileUtils.copyDirectory(new File(sourceFileFullPath), new File(targetFileFullPath));
            return true;
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
        return false;
    }

    /**
     * 移动文件到指定位置
     *
     * @param sourceFileFullPath 要移动的文件全路径
     * @param targetFileFullPath 移动文件到目标位置的目录全路径
     * @return 是否复制成功, true:成功;否则失败
     */
    public static boolean moveFileToTarget(String sourceFileFullPath, String targetFileFullPath) {
        try {
            FileUtils.moveFile(new File(sourceFileFullPath), new File(targetFileFullPath));
            return true;
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
        return false;
    }

    /**
     * 移动文件夹到指定位置
     *
     * @param sourceFileFullPath 要移动的文件全路径
     * @param targetFileFullPath 移动文件到目标位置的目录全路径
     * @return 是否复制成功, true:成功;否则失败
     */
    public static boolean moveDirectoryToTarget(String sourceFileFullPath, String targetFileFullPath) {
        try {
            FileUtils.moveDirectory(new File(sourceFileFullPath), new File(targetFileFullPath));
            return true;
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
        return false;
    }

    /**
     * 解压
     *
     * @param zipFilePath  zip文件路径
     * @param desDirectory 解压的目标路径
     */
    public static boolean unzip(String zipFilePath, String desDirectory) {
        File desDir = new File(desDirectory);
        if (!desDir.exists()) {
            boolean mkdirSuccess = desDir.mkdirs();
            if (!mkdirSuccess) {
                log.error("创建解压目标文件夹失败");
                return false;
            }
        }
        // 读入流
        try (ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(zipFilePath))) {
            // 遍历每一个文件
            ZipEntry zipEntry = zipInputStream.getNextEntry();
            while (zipEntry != null) {
                String unzipFilePath = desDirectory + File.separator + zipEntry.getName();
                if (zipEntry.isDirectory()) {
                    // 直接创建
                    mkdir(new File(unzipFilePath));
                } else {
                    File file = new File(unzipFilePath);
                    // 创建父目录
                    mkdir(file.getParentFile());
                    // 写出文件流
                    BufferedOutputStream bufferedOutputStream =
                            new BufferedOutputStream(new FileOutputStream(unzipFilePath));
                    byte[] bytes = new byte[1024];
                    int readLen;
                    while ((readLen = zipInputStream.read(bytes)) != -1) {
                        bufferedOutputStream.write(bytes, 0, readLen);
                    }
                    bufferedOutputStream.close();
                }
                zipInputStream.closeEntry();
                zipEntry = zipInputStream.getNextEntry();
            }
            return true;
        } catch (Exception e) {
            log.error("解压文件失败");
            return false;
        }
    }

    public static void mkdir(File file) {
        if (null == file || file.exists()) {
            return;
        }
        boolean b = file.mkdirs();
        if (!b) {
            log.info("父路径文件夹创建失败");
        }
    }


    /**
     * 获取路径下的所有文件/文件夹
     *
     * @param directoryPath  需要遍历的文件夹路径
     * @param isAddDirectory 是否将子文件夹的路径也添加到list集合中
     * @return 路径
     */
    public static List<String> getAllFile(String directoryPath, boolean isAddDirectory) {
        List<String> list = new ArrayList<>();
        File baseFile = new File(directoryPath);
        if (baseFile.isFile() || !baseFile.exists()) {
            return list;
        }
        File[] files = baseFile.listFiles();
        if (files == null) {
            return new ArrayList<>();
        }
        for (File file : files) {
            if (file.isDirectory()) {
                if (isAddDirectory) {
                    list.add(file.getAbsolutePath());
                }
                list.addAll(getAllFile(file.getAbsolutePath(), isAddDirectory));
            } else {
                list.add(file.getAbsolutePath());
            }
        }
        return list;
    }

    /**
     * 生成zip压缩文件
     *
     * @param filePaths        文件信息 {"fileName":"222.tif"} {"filePath","E:\\ceshi\\222.tif"};
     * @param zipFilePath      压缩路径 "E:\\downloadCESHI\\"+zipName;
     * @param keepDirStructure 压缩是否保持原路径结构
     */
    public static boolean compress(List<Map<String, String>> filePaths, String zipFilePath, Boolean keepDirStructure) {
        byte[] buf = new byte[1024];
        File zipFile = new File(zipFilePath);
        try {
            if (!zipFile.exists()) {
                boolean newFileFlag = zipFile.createNewFile();
                if (!newFileFlag) {
                    return false;
                }
            }
            ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile));
            for (Map<String, String> filePath : filePaths) {
                String relativePath = filePath.get("filePath");
                String relativeName = filePath.get("fileName");
                if (StringUtils.isEmpty(relativePath)) {
                    continue;
                }
                File sourceFile = new File(relativePath);
                if (!sourceFile.exists()) {
                    continue;
                }
                FileInputStream fis = new FileInputStream(sourceFile);
                if (keepDirStructure != null && keepDirStructure) {
                    zos.putNextEntry(new ZipEntry(relativePath));
                } else {
                    zos.putNextEntry(new ZipEntry(relativeName));
                }
                int len;
                while ((len = fis.read(buf)) > 0) {
                    zos.write(buf, 0, len);
                }
                zos.closeEntry();
                fis.close();
            }
            zos.close();
            return true;
        } catch (Exception e) {
            log.error("压缩异常", e);
            return false;
        }
    }

    /**
     * 生成zip压缩文件
     *
     * @param directory        待压缩的文件夹
     * @param zipFilePath      压缩路径
     * @param keepDirStructure 压缩是否保持原路径结构
     */
    public static boolean compressDirectory(File directory, String zipFilePath, boolean keepDirStructure) {
        if (!directory.isDirectory()) {
            log.error("文件不是文件夹 :{}", directory.getName());
            return false;
        }
        File zipFile = new File(zipFilePath);
        try {
            if (!zipFile.exists()) {
                File parentFile = zipFile.getParentFile();
                boolean dirs = parentFile.mkdirs();
                if (!dirs) {
                    log.warn("文件夹创建失败 :{}", parentFile.getName());
                    return false;
                }
                boolean newFileFlag = zipFile.createNewFile();
                if (!newFileFlag) {
                    return false;
                }
            }
            String name = directory.getName();
            ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile));
            compress(directory, zos, name, keepDirStructure);
            zos.close();
            return true;
        } catch (Exception e) {
            log.error("压缩异常", e);
            return false;
        }
    }

    /**
     * 递归压缩方法
     *
     * @param sourceFile       源文件
     * @param zos              zip输出流
     * @param name             压缩后的名称
     * @param keepDirStructure 是否保留原来的目录结构,true:保留目录结构;
     *                         false:所有文件跑到压缩包根目录下
     */

    private static void compress(File sourceFile, ZipOutputStream zos, String name,
                                 boolean keepDirStructure) throws Exception {
        byte[] buf = new byte[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(), true);
                    } else {
                        compress(file, zos, file.getName(), false);
                    }
                }
            }
        }
    }

    public static void deleteDirectory(String filePath) {
        if (StringUtils.isEmpty(filePath)) {
            log.error("解析生成文件失败");
            return;
        }
        File file = new File(filePath);
        try {
            FileUtils.deleteDirectory(file);
        } catch (IOException e) {
            log.error("删除文件目录失败", e);
        }
    }

    public static void deleteDirectory(File file) {
        if (file == null) {
            log.error("解析生成文件失败");
            return;
        }
        try {
            FileUtils.deleteDirectory(file);
        } catch (IOException e) {
            log.error("删除文件目录失败", e);
        }
    }

    /**
     * 将文件对象转换为字符串
     *
     * @param filePath 文件路径
     * @return
     */
    public static String readFileToString(String filePath) {
        File file = new File(filePath);
        if (!file.exists()) {
            return null;
        }
        try {
            return FileUtils.readFileToString(file);
        } catch (IOException e) {
            e.printStackTrace();
            log.error("文件对象转换为字符串", e);
            return null;
        }
    }

    /**
     * 将json数据信息存入相应的文件中
     *
     * @param filePath 文件路径
     * @param fileName 文件名称
     * @param content  文件内容
     * @return 是否成功
     */
    public static String createFile(String filePath, String fileName, String content) {
        File dir = new File(filePath);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        File file = new File(filePath + File.separator + fileName);
        if (!file.exists()) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                log.error("文件创建失败", e);
            }
        }

        try (OutputStream outputStream = new FileOutputStream(file.getAbsoluteFile());
             OutputStreamWriter out = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8)) {
            out.write(content);
            out.flush();

        } catch (Exception e1) {
            log.error("文件创建失败", e1);
            return null;
        }
        return file.getPath();
    }

    /**
     * 删除文件数据
     *
     * @param filePath 文件路径
     * @return 状态
     */
    public static boolean deleteFile(String filePath) {
        if (StringUtils.isEmpty(filePath)) {
            return false;
        }
        File file = new File(filePath);
        return file.delete();
    }

    /**
     * 根据文件全路径生成相应的MD5数值
     *
     * @param fileFullPath 文件全路径信息
     * @return 文件对应的md5
     */
    public static String generateFileMd5(String fileFullPath) {
        File file = new File(fileFullPath);
        if (file.isDirectory()) {
            return Md5Utils.calculateFolderMD5(fileFullPath);
        }
        try (FileInputStream fileInputStream = new FileInputStream(fileFullPath)) {
            return DigestUtils.md5Hex(fileInputStream);
        } catch (IOException e) {
            log.error("DigestUtils.md5Hex error", e);
            return null;
        }
    }

    /**
     * 字节数组写出到文件
     * 字节数组读取到程序中 ByteArrayInputStream
     * 程序写出到文件 FileOutputStream
     *
     * @param src          字节数组
     * @param distFilePath 文件存储本地路径
     */
    public static boolean toFile(byte[] src, String distFilePath) {
        if (src == null || src.length == 0) {
            return false;
        }
        try (InputStream is = new ByteArrayInputStream(src);
             OutputStream os = new FileOutputStream(distFilePath);) {
            byte[] flush = new byte[1024 * 10];
            int len = -1;
            while ((len = is.read(flush)) != -1) {
                os.write(flush, 0, len);
                os.flush();
            }
        } catch (IOException e) {
            log.error("byte[] to file error.", e);
        }
        File file = new File(distFilePath);
        return file.exists();
    }

    /**
     * 修改linux环境下文件权限为755
     *
     * @param fullFilePath 文件全路径
     */
    public static void changeFilePermission755(String fullFilePath) {
        File file = new File(fullFilePath);
        log.info("{} can 1 file.canExecute()={}", fullFilePath, file.canExecute());

        //设置权限
        Set<PosixFilePermission> perms = new HashSet<>();
        perms.add(PosixFilePermission.OWNER_READ);
        perms.add(PosixFilePermission.OWNER_WRITE);
        perms.add(PosixFilePermission.OWNER_EXECUTE);
        perms.add(PosixFilePermission.GROUP_READ);
        perms.add(PosixFilePermission.GROUP_EXECUTE);
        perms.add(PosixFilePermission.OTHERS_READ);
        perms.add(PosixFilePermission.OTHERS_EXECUTE);

        Path path = Paths.get(fullFilePath);
        try {
            Files.walk(path).forEach(
                    p -> {
                        try {
                            Files.setPosixFilePermissions(p, perms);//修改文件的权限
                        } catch (Exception e) {
                            log.error("文件权限修改失败", e);
                        }
                    }
            );
        } catch (IOException e) {
            log.error("文件权限修改失败", e);
        }
        log.info("{} can 2 file.canExecute()={}", fullFilePath, file.canExecute());
    }


    /**
     * 修改linux环境下文件权限为777
     *
     * @param filePath 文件全路径
     */
    public static void changeFilePermission777(String filePath) {
        File file = new File(filePath);
        log.info("{} can 1 file.canExecute()={}", filePath, file.canExecute());

        //设置权限
        Set<PosixFilePermission> perms = new HashSet<>();
        perms.add(PosixFilePermission.OWNER_READ);
        perms.add(PosixFilePermission.OWNER_WRITE);
        perms.add(PosixFilePermission.OWNER_EXECUTE);
        perms.add(PosixFilePermission.GROUP_READ);
        perms.add(PosixFilePermission.GROUP_WRITE);
        perms.add(PosixFilePermission.GROUP_EXECUTE);
        perms.add(PosixFilePermission.OTHERS_READ);
        perms.add(PosixFilePermission.OTHERS_WRITE);
        perms.add(PosixFilePermission.OTHERS_EXECUTE);

        Path path = Paths.get(filePath);
        try {
            Files.walk(path).forEach(
                    p -> {
                        try {
                            Files.setPosixFilePermissions(p, perms);//修改文件的权限
                        } catch (Exception e) {
                            log.error("文件权限修改失败", e);
                        }
                    }
            );
        } catch (IOException e) {
            log.error("文件权限修改失败", e);
        }
        log.info("{} can 2 file.canExecute()={}", path, file.canExecute());
    }
}
相关推荐
Hello-Brand1 分钟前
Java核心知识体系10-线程管理
java·高并发·多线程·并发·多线程模型·线程管理
乐悠小码7 分钟前
数据结构------队列(Java语言描述)
java·开发语言·数据结构·链表·队列
史努比.9 分钟前
Pod控制器
java·开发语言
2的n次方_12 分钟前
二维费用背包问题
java·算法·动态规划
皮皮林55112 分钟前
警惕!List.of() vs Arrays.asList():这些隐藏差异可能让你的代码崩溃!
java
莳光.12 分钟前
122、java的LambdaQueryWapper的条件拼接实现数据sql中and (column1 =1 or column1 is null)
java·mybatis
程序猿麦小七17 分钟前
基于springboot的景区网页设计与实现
java·spring boot·后端·旅游·景区
weisian15123 分钟前
认证鉴权框架SpringSecurity-2--重点组件和过滤器链篇
java·安全
蓝田~25 分钟前
SpringBoot-自定义注解,拦截器
java·spring boot·后端
theLuckyLong26 分钟前
SpringBoot后端解决跨域问题
spring boot·后端·python