You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Node.js内置zlib模块从zip压缩包中提取单个指定文件

实现前提说明

Node.js 内置的 zlib 模块仅负责处理原始的 deflate/gzip 压缩数据流,本身不包含 ZIP 归档格式的文件结构解析能力。ZIP 是归档+压缩结合的格式,包含文件头、元数据、校验值等额外结构,所以我们需要手动解析 ZIP 结构筛选目标文件,再调用 zlib 解压对应数据段即可。

完整实现代码
const fs = require('fs');
const zlib = require('zlib');

// 本地文件头签名,ZIP规范固定值
const LOCAL_FILE_HEADER_SIGNATURE = 0x04034b50;
// 压缩方法:deflate对应值8,未压缩对应0
const COMPRESSION_METHOD_DEFLATE = 8;

async function extractTest1FromZip() {
  // 读取整个zip文件到buffer
  const zipBuffer = await fs.promises.readFile('./test.zip');
  let offset = 0;

  while (offset < zipBuffer.length - 4) {
    // 读取当前块的签名
    const signature = zipBuffer.readUInt32LE(offset);
    // 读到目录头就终止遍历,所有本地文件都在目录头之前
    if (signature === 0x02014b50) break;
    if (signature !== LOCAL_FILE_HEADER_SIGNATURE) {
      offset += 1;
      continue;
    }

    // 解析本地文件头固定字段,对应ZIP规范偏移
    const compressionMethod = zipBuffer.readUInt16LE(offset + 8);
    const compressedSize = zipBuffer.readUInt32LE(offset + 18);
    const uncompressedSize = zipBuffer.readUInt32LE(offset + 22);
    const fileNameLength = zipBuffer.readUInt16LE(offset + 26);
    const extraFieldLength = zipBuffer.readUInt16LE(offset + 28);

    // 读取文件名
    const fileName = zipBuffer.toString('utf8', offset + 30, offset + 30 + fileNameLength);
    
    // 匹配到目标文件
    if (fileName === 'test1.txt') {
      // 计算压缩数据的起始偏移
      const dataOffset = offset + 30 + fileNameLength + extraFieldLength;
      // 截取压缩数据段
      const compressedData = zipBuffer.subarray(dataOffset, dataOffset + compressedSize);

      // 解压数据,zip的deflate数据无zlib头,所以用inflateRaw
      const uncompressedData = compressionMethod === COMPRESSION_METHOD_DEFLATE 
        ? zlib.inflateRawSync(compressedData)
        : compressedData;

      // 写入解压后的文件
      await fs.promises.writeFile('./test1.txt', uncompressedData);
      console.log('test1.txt 提取成功');
      return;
    }

    // 跳过当前文件的整个块,处理下一个文件
    offset += 30 + fileNameLength + extraFieldLength + compressedSize;
  }

  console.log('未找到目标文件 test1.txt');
}

extractTest1FromZip().catch(err => console.error('提取失败:', err));
注意事项
  • 上述实现仅适配无加密、使用标准deflate压缩、无分片的常规ZIP包,足够覆盖绝大多数普通使用场景
  • 实现完全依赖Node.js内置模块,不需要安装任何第三方依赖

内容的提问来源于stack exchange,提问作者Moin Ahmad Ansari

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 21:45:01