背景:将zip文件传到linux服务器上,在服务器进行解压操作

  • 创建临时文件夹(Temp)
  • 通过MultipartFile 接受前端传来的文件(zip文件),将其转成流,方便ZIP类进行解压
  • 使用ZIP进行解压操作

创建临时文件夹

使用Path接受 Files创建的临时文件夹路径

源码注释“在默认的临时文件目录中创建一个新目录,使用给定的前缀生成其名称。结果路径与默认文件系统相关联。”

Path tempDir = Files.createTempDirectory("upload");
ZipInputStream zis = new ZipInputStream(zipFile.getInputStream());

Zip压缩文件夹下有许多的实体文件

使用ZipEntry entry接收

使用While循环先赋值后判空,ZipInputStream.getNextEntry()返回值如果为空,说明zip下已没有未读取的内容了

entry = zis.getNextEntry()
while ((entry = zis.getNextEntry()) != null) {
 ... 
}

既然是文件我们就需要将流转换成文件

使用File接收实体文件(File用于描述一个文件)

//mac、windows、linux下文件路径不同,用resolve方法拼接路径,他会根据系统不通拼接不同路径
File file = tempDir.resolve(fileName).toFile();

解压的实际操作

read方法返回值 读取的实际字节数,如果到达条目末尾,则为-1

  • 输出file文件流
/**
 * @description 从存档(ZIP)中提取文件内容
 * @author weicheng.lu
 * @date 2021/3/1 9:53 上午
 * @param file
 * @param zis
 * @return
 */
private static final int BUFFER = 2048;

private static void extractFileContentFromArchive(File file, ZipInputStream zis) throws IOException {
    FileOutputStream fos = new FileOutputStream(file);
    BufferedOutputStream bos = new BufferedOutputStream(fos, BUFFER);
    int len = 0;
    byte data[] = new byte[BUFFER];
    while ((len = zis.read(data, 0, BUFFER)) != -1) {
        bos.write(data, 0, len);
    }
    bos.flush();
    bos.close();
}

此时File还只是存放在内存中,还要进行判断,文件是否存在,如果不存在,则创建新文件

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

完整代码

@Override
    public void unZip(MultipartFile zipFile) throws IOException {
        //上传文件
        Path tempDir = Files.createTempDirectory("upload");
        //获取Zip流
        ZipInputStream zis = new ZipInputStream(zipFile.getInputStream());
        //Zip下每个文件
        ZipEntry entry;
        //先赋值后判空
        while ((entry = zis.getNextEntry()) != null) {
            String fileName = entry.getName();
            //macos特有的文件夹
            if (fileName.contains("MACOSX")) {
                continue;
            }
            //mac、windows、linux下文件路径不同,用resolve方法拼接路径,他会根据系统不通拼接不同路径
            File file = tempDir.resolve(fileName).toFile();
            //将读取到的文件输出
            if (!entry.isDirectory()) {
                extractFileContentFromArchive(file, zis);
            } else {
                if (!file.exists()) {
                    file.mkdirs();
                }
            }
            zis.closeEntry();
        }
    }

    /**
     * @description 从存档(ZIP)中提取文件内容
     * @author weicheng.lu
     * @date 2021/3/1 9:53 上午
     * @param file
     * @param zis
     * @return
     */
    private static final int BUFFER = 2048;

    private static void extractFileContentFromArchive(File file, ZipInputStream zis) throws IOException {
        FileOutputStream fos = new FileOutputStream(file);
        BufferedOutputStream bos = new BufferedOutputStream(fos, BUFFER);
        int len = 0;
        byte data[] = new byte[BUFFER];
        while ((len = zis.read(data, 0, BUFFER)) != -1) {
            bos.write(data, 0, len);
        }
        bos.flush();
        bos.close();
    }