ZIP文件格式分析

官方文档

https://pkware.cachefly.net/webdocs/APPNOTE/APPNOTE-6.2.0.txt

格式说明

在官方文档中给出的ZIP格式如下:

  Overall .ZIP file format:

    [local file header 1]
    [file data 1]
    [data descriptor 1]
    . 
    .
    .
    [local file header n]
    [file data n]
    [data descriptor n]
    [archive decryption header] (EFS)
    [archive extra data record] (EFS)
    [central directory]
    [zip64 end of central directory record]
    [zip64 end of central directory locator] 
    [end of central directory record]

通常情况下,我们用到的ZIP文件格式:

[local file header + file data + data descriptor]{1,n} + central directory + end of central directory record
即
[文件头+文件数据+数据描述符]{此处可重复n次}+核心目录+目录结束标识

当压缩包中有多个文件时,就会有多个[文件头+文件数据+数据描述符]

本片文章讨论的就是这种通常用到的ZIP文件格式,若想了解完整的ZIP文件格式,请看官方文档。

压缩源文件数据区

[local file header + file data + data descriptor]

记录着压缩的所有文件的内容信息,每个压缩文件都由local file header 、file data、data descriptor三部分组成,在这个数据区中每一个压缩的源文件/目录都是一条记录。

### local file header 文件头
用于标识该文件的开始,记录了该压缩文件的信息。

Offset Bytes Description
0 4 Local file header signature = 0x04034b50 (read as a little-endian number) 文件头标识,值固定(0x04034b50)
4 2 Version needed to extract (minimum) 解压文件所需 pkware最低版本
6 2 General purpose bit flag 通用比特标志位(置比特0位=加密,详情见后)
8 2 Compression method 压缩方式(详情见后)
10 2 File last modification time 文件最后修改时间
12 2 File last modification date 文件最后修改日期
14 4 CRC-32 CRC-32校验码
18 4 Compressed size 压缩后的大小
22 4 Uncompressed size 未压缩的大小
26 2 File name length (n) 文件名长度
28 2 Extra field length (m) 扩展区长度
30 n File name 文件名
30+n m Extra field 扩展区
general purpose bit flag: (2 bytes) 通用位标记
      Bit 0: If set, indicates that the file is encrypted.

      (For Method 6 - Imploding)
      Bit 1: If the compression method used was type 6
  • 28
    点赞
  • 68
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
以下是一个示例代码,演示如何使用Java下载zip文件并解析其中的Excel文件,获取数据。 ```java import java.io.*; import java.util.*; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.*; public class ZipExcelParser { public static void main(String[] args) throws Exception { // Step 1: 下载zip文件 String url = "https://example.com/file.zip"; // zip文件的URL String zipFilePath = "file.zip"; // 下载后的zip文件路径 downloadFile(url, zipFilePath); // Step 2: 解析Excel文件 String excelFilePath = null; // Excel文件路径 try (ZipInputStream zip = new ZipInputStream(new FileInputStream(zipFilePath))) { ZipEntry entry = zip.getNextEntry(); while (entry != null) { String fileName = entry.getName(); if (fileName.endsWith(".xlsx")) { // 只处理.xlsx文件 excelFilePath = fileName; File file = new File(excelFilePath); FileOutputStream fos = new FileOutputStream(file); byte[] bytes = new byte[1024]; int length; while ((length = zip.read(bytes)) >= 0) { fos.write(bytes, 0, length); } fos.close(); break; } entry = zip.getNextEntry(); } } // Step 3: 获取Excel数据 List<List<String>> data = new ArrayList<>(); Workbook workbook = new XSSFWorkbook(new FileInputStream(excelFilePath)); Sheet sheet = workbook.getSheetAt(0); // 假设数据在第一个Sheet中 for (Row row : sheet) { List<String> rowData = new ArrayList<>(); for (Cell cell : row) { rowData.add(cell.toString()); } data.add(rowData); } workbook.close(); // 打印数据 for (List<String> rowData : data) { System.out.println(String.join(",", rowData)); } } // 下载文件 private static void downloadFile(String url, String filePath) throws Exception { BufferedInputStream in = new BufferedInputStream(new URL(url).openStream()); FileOutputStream fos = new FileOutputStream(filePath); byte[] dataBuffer = new byte[1024]; int bytesRead; while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) { fos.write(dataBuffer, 0, bytesRead); } fos.close(); in.close(); } } ``` 请注意,此示例代码使用了Apache POI库来解析Excel文件。如果您尚未安装它,请在项目中添加以下依赖项: ```xml <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>4.1.2</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>4.1.2</version> </dependency> ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值