Java 写 ZIP 文件夹及文件

搜到的都是些什么妖魔鬼怪

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

/**
 * ZIP 文件结构
 *
 * @author seliote
 * @since 2022-07-07
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ZipStruct {

    public static final Integer TYPE_DIR = 1;
    public static final Integer TYPE_FILE = 2;

    private Integer type;
    private String name;
    private byte[] content;
    private List<ZipStruct> sub;
}

import cn.hutool.core.io.FileUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.lang.NonNull;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import static com.example.test.zip.ZipStruct.TYPE_DIR;
import static com.example.test.zip.ZipStruct.TYPE_FILE;

/**
 * ZIP 压缩工具
 *
 * @author Li Yangdi
 * @since 2022-07-07
 */
@Slf4j
public class ZipUtils {

    private static final String PATH_SEP = "/";

    /**
     * 创建一个 ZIP 文件
     *
     * @return 文件流
     */
    public static byte[] zip(@NonNull List<ZipStruct> structs) {
        try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
            try (ZipOutputStream zos = new ZipOutputStream(baos)) {
                for (ZipStruct struct : structs) {
                    zip(zos, struct, "");
                }
            }
            return baos.toByteArray();
        } catch (IOException e) {
            log.warn("Failed create zip file", e);
            throw new RuntimeException(e);
        }
    }

    private static void zip(ZipOutputStream zos, ZipStruct struct, String parentPath) throws IOException {
        String path = parentPath.isEmpty() ? struct.getName() : parentPath + PATH_SEP + struct.getName();
        if (struct.getType().equals(TYPE_DIR)) {
            zos.putNextEntry(new ZipEntry(path + PATH_SEP));
            zos.closeEntry();
            if (struct.getSub() != null && struct.getSub().size() != 0) {
                for (ZipStruct subStruct : struct.getSub()) {
                    zip(zos, subStruct, path);
                }
            }
        } else if (struct.getType().equals(ZipStruct.TYPE_FILE)) {
            zos.putNextEntry(new ZipEntry(path));
            zos.write(struct.getContent());
            zos.closeEntry();
        } else {
            throw new RuntimeException("Unknown ZIP entry type of " + struct.getType());
        }
    }

    public static void main(String[] args) {
        List<ZipStruct> structs = new ArrayList<>();
        ZipStruct emptyDir = ZipStruct.builder().type(TYPE_DIR).name("空文件夹").build();
        ZipStruct txtDir = ZipStruct.builder().type(TYPE_DIR).name("文本文件夹").build();
        structs.add(emptyDir);
        structs.add(txtDir);
        ZipStruct txtFile = ZipStruct.builder().type(TYPE_FILE).name("文本文件.txt")
                .content("我是中文".getBytes(StandardCharsets.UTF_8)).build();
        txtDir.setSub(new ArrayList<>() {{
            add(txtFile);
        }});
        FileUtil.writeBytes(zip(structs), "C:\\Users\\seliote\\Downloads\\测试.zip");
    }
}
posted @ 2022-07-07 17:03  seliote  阅读(239)  评论(0)    收藏  举报