Java는 여러 파일을 zip 패키지로 압축하고(중간에 임시 파일이 생성되지 않고 zip 바이너리 스트림으로 직접 압축됨) zip 패키지 바이너리 스트림을 파일로 압축 해제합니다.

Java는 여러 파일을 zip 패키지로 압축하고 zip 패키지를 압축 해제하고 여러 파일을 zip 파일 스트림으로 압축하고 zip 바이너리 스트림을 압축 해제합니다.

이 블로그는 두 가지 방법을 제공합니다.

  1. 미리 압축할 여러 파일을 생성한 다음 여러 레이어 또는 폴더 레이어를 읽어 압축된 zip 패키지를 통과합니다.
  2. 원본 파일 이름과 바이너리 스트림을 직접 사용하고 zip 패키지의 바이너리 스트림을 압축하여 반환하며 중간에 중복 파일을 생성하지 않습니다
    .
  3. 압축 해제 zip 파일 또는 zip 파일 스트림 확인;

1. 렌더링

두 파일을 zip 패키지로 압축하고 zip 패키지 파일과 zip 바이너리 스트림을 각각 분석하고 다음과 같이 파일과 파일 콘텐츠의 자세한 렌더링을 인쇄합니다 .

여기에 이미지 설명 삽입

2. 소스코드

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;


public class FileUtil {
    
    

    public static void main(String[] args) throws Exception {
    
    
        long timeStamp = System.currentTimeMillis();
        String uuid = UUID.randomUUID().toString();
        // 生成本地文件,然后压缩,压缩完成清除本地文件及冗余文件夹
        zipTest1(uuid, timeStamp);

        // 不生成中间文件,直接使用文件名称+文件流进行压缩 更优
        zipTest2(uuid, timeStamp);
    }

    private static void zipTest2(String uuid, long timeStamp) throws IOException {
    
    
        String zipFileName = String.format("%s_%s.zip", uuid, timeStamp);
        String imgFileName = String.format("%s_%s_%s.json", "img", uuid, timeStamp);
        String referInfoFile = String.format("%s_%s_%s.json", "ref", uuid, timeStamp);

        String[] fileNames = new String[]{
    
    imgFileName, referInfoFile};
        List<byte[]> bytesList = new ArrayList<>();
        byte[] file0 = imgFileName.toString().getBytes();
        byte[] file1 = referInfoFile.toString().getBytes();
        bytesList.add(file0);
        bytesList.add(file1);

        // zip压缩流
        byte[] rodZip = packageZipToBytes(fileNames, bytesList);

        readAndParseZip(zipFileName, rodZip);
    }

    private static void zipTest1(String uuid, long timeStamp) throws Exception {
    
    
        String path = System.getProperty("user.dir") + File.separator + uuid + "_" + timeStamp + File.separator;
        String resPath = System.getProperty("user.dir") + File.separator + "out" + File.separator + uuid + "_" + timeStamp;

        deleteDirectory(path);
        delOrCreateDir(path);
        delOrCreateDir(resPath);
        String imgFileName = String.format("%s%s_%s_%s.json", path, "img", uuid, timeStamp);
        String referInfoFile = String.format("%s%s_%s_%s.json", path, "ref", uuid, timeStamp);
        try (FileWriter fileWriter = new FileWriter(referInfoFile)) {
    
    
            fileWriter.write(referInfoFile.toString());
        }
        try (FileWriter fileWriter = new FileWriter(imgFileName)) {
    
    
            fileWriter.write(imgFileName.toString());
        }

        System.out.println("zip start ---------------" + System.currentTimeMillis());
        FileUtil test3 = new FileUtil();
        String packagePath = path;  //选中的文件夹
        test3.packageZip(packagePath, resPath + ".zip");
        System.out.println("zip finish ---------------" + System.currentTimeMillis());

        // 删除冗余文件,文件夹
        deleteDirectory(path);
        deleteDirectory(resPath);
        deleteDirectory(resPath);
    }

    /**
     * 压缩多个文件为zip包文件流
     *
     * @param fileNames 文件名称
     * @param byteLists 文件流
     * @return
     */
    public static byte[] packageZipToBytes(String[] fileNames, List<byte[]> byteLists) throws IOException {
    
    
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ZipOutputStream zipOutputStream = null;
        try {
    
    
            zipOutputStream = new ZipOutputStream(bos);
            for (int i = 0; i < fileNames.length; i++) {
    
    
                String fileName = fileNames[i];
                fileName = fileName.substring(fileName.lastIndexOf(File.separator) + 1);
                byte[] content = byteLists.get(i);
                // 依次对每个文件都压缩
                try {
    
    
                    zipOutputStream.putNextEntry(new ZipEntry(fileName));
                    zipOutputStream.write(content);
                } catch (IOException e) {
    
    
                    throw new RuntimeException(e);
                }
            }
            zipOutputStream.close();
            bos.close();
        } catch (FileNotFoundException e) {
    
    
            throw new RuntimeException(e);
        } catch (IOException e) {
    
    
            throw new RuntimeException(e);
        }

        byte[] zipOutBytes = bos.toByteArray();
/*        OutputStream fos = new FileOutputStream("D:\\study\\ark-common-model\\out\\aaaaaaaa_1689583754986.zip");
        fos.write(zipOutBytes, 0, zipOutBytes.length);
        fos.close();*/

        return zipOutBytes;
    }

    private static void readAndParseZip(String zipFilePath, byte[] rodZip) {
    
    
        ByteArrayInputStream fis = null;
        FileInputStream fileInputStream = null;
        ZipInputStream zis = null;
        try {
    
    
            if (rodZip != null) {
    
    
                fis = new ByteArrayInputStream(rodZip);
                zis = new ZipInputStream(fis);
            } else {
    
    
                fileInputStream = new FileInputStream(zipFilePath);
                zis = new ZipInputStream(fileInputStream);
            }

            ZipEntry zipEntry = zis.getNextEntry();
            while (zipEntry != null) {
    
    
                // 如果该项是一个文件
                if (!zipEntry.isDirectory()) {
    
    
                    String fileName = zipEntry.getName();
                    ByteArrayOutputStream bos = new ByteArrayOutputStream();

                    byte[] buffer = new byte[1024];
                    int len;
                    while ((len = zis.read(buffer)) > 0) {
    
    
                        bos.write(buffer, 0, len);
                    }
                    // 将解压出的文件流输出到控制台
                    String content = bos.toString();
                    System.out.println("fileName: " + fileName + ",content: " + content);
                }
                zis.closeEntry();
                zipEntry = zis.getNextEntry();
            }

            zis.close();
            fis.close();
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
    }

    public static void delOrCreateDir(String imgPath) {
    
    
        File file = new File(imgPath);

        if (!file.getParentFile().exists()) {
    
    
            //上级目录不存在,创建上级目录
            file.getParentFile().mkdirs();
        } else {
    
    
//            FileUtils.deleteFolder(imgPath);
        }
        file.mkdirs();
    }

    /**
     * 根据路径删除指定的目录或文件,无论存在与否
     *
     * @param sPath 要删除的目录或文件
     * @return 删除成功返回 true,否则返回 false。
     */
    public static boolean deleteFolder(String sPath) {
    
    
        boolean flag = false;
        File file = new File(sPath);
        // 判断目录或文件是否存在
        if (!file.exists()) {
    
      // 不存在返回 false
            return flag;
        } else {
    
    
            // 判断是否为文件
            if (file.isFile()) {
    
      // 为文件时调用删除文件方法
                return deleteFile(sPath);
            } else {
    
      // 为目录时调用删除目录方法
                return deleteDirectory(sPath);
            }
        }
    }

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

    /**
     * 删除目录(文件夹)以及目录下的文件
     *
     * @param sPath 被删除目录的文件路径
     * @return 目录删除成功返回true,否则返回false
     */
    public static boolean deleteDirectory(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;
                }
            } //删除子目录
            else {
    
    
                flag = deleteDirectory(files[i].getAbsolutePath());
                if (!flag) {
    
    
                    break;
                }
            }
        }
        if (!flag) {
    
    
            return false;
        }
        //删除当前目录
        if (dirFile.delete()) {
    
    
//            dirFile.getParentFile().delete();
            return true;
        } else {
    
    
//            dirFile.getParentFile().delete();
            return false;
        }
    }


    public void packageZip(String filesPath, String resPath) throws Exception {
    
    
        // 要被压缩的文件夹
        File file = new File(filesPath);   //需要压缩的文件夹
        File zipFile = new File(resPath);
        ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFile));
        isDirectory(file, zipOut, "", true);   //判断是否为文件夹
        zipOut.close();
    }

    public void isDirectory(File file, ZipOutputStream zipOutputStream, String filePath, boolean flag) throws
            IOException {
    
    
        //判断是否为问加减
        if (file.isDirectory()) {
    
    
            File[] files = file.listFiles();  //获取该文件夹下所有文件(包含文件夹)
            filePath = flag == true ? file.getName() : filePath + File.separator + file.getName();   //首次为选中的文件夹,即根目录,之后递归实现拼接目录
            for (int i = 0; i < files.length; ++i) {
    
    
                //判断子文件是否为文件夹
                if (files[i].isDirectory()) {
    
    
                    System.out.println("-----" + files[i].getName());
                    //进入递归,flag置false 即当前文件夹下仍包含文件夹
                    isDirectory(files[i], zipOutputStream, filePath, false);
                } else {
    
    
                    System.out.println("fileName: " + files[i].getName());
                    //不为文件夹则进行压缩
                    InputStream input = new FileInputStream(files[i]);
                    zipOutputStream.putNextEntry(new ZipEntry(files[i].getName()));
                    int temp = 0;
                    while ((temp = input.read()) != -1) {
    
    
                        zipOutputStream.write(temp);
                    }
                    input.close();
                }
            }
        } else {
    
    
            //将子文件夹下的文件进行压缩
            InputStream input = new FileInputStream(file);
            zipOutputStream.putNextEntry(new ZipEntry(file.getPath()));
            int temp = 0;
            while ((temp = input.read()) != -1) {
    
    
                zipOutputStream.write(temp);
            }
            input.close();
        }
    }
}

추천

출처blog.csdn.net/qq_40985985/article/details/131780780