Node.js中如何提取Deflate64压缩格式的Zip文件?
解决Node.js无法解压Deflate64格式Zip文件的问题
你遇到的unsupported compression method: 9错误,本质是Deflate64(压缩方法编号9)属于WinZip专有压缩格式,你试过的yauzl、adm-zip等Node.js原生Zip库都没实现对它的支持。下面给两个可行的解决方案:
方案一:调用7-Zip工具(最稳定可靠)
7-Zip对几乎所有压缩格式都有完美支持,包括Deflate64。我们可以通过Node.js子进程调用它的命令行工具完成解压。
- 安装依赖:
npm install 7zip-bin
- 修改解压代码:
const { execFile } = require('child_process'); const path = require('path'); const sevenBin = require('7zip-bin'); const fs = require('fs'); exports.unzip = function (zipPath, targetDir, completeHandler, progressHandler, errHandler) { // 确保目标目录存在 fs.mkdirSync(targetDir, { recursive: true }); // 获取7-Zip命令行工具路径 const sevenZipPath = sevenBin.path7za; // 解压命令参数:x=提取文件,-o指定输出目录,-y自动确认所有操作 const args = ['x', zipPath, `-o${targetDir}`, '-y']; const child = execFile(sevenZipPath, args, (err, stdout, stderr) => { if (err) { errHandler?.(err); return; } completeHandler?.(); }); // 可选:解析7-Zip输出的进度信息 child.stdout.on('data', (data) => { const output = data.toString(); const progressMatch = output.match(/(\d+)%/); if (progressMatch) { progressHandler?.(parseInt(progressMatch[1], 10)); } }); child.stderr.on('data', (data) => { console.error('7-Zip错误输出:', data.toString()); }); };
这个方案不需要处理复杂的压缩格式细节,兼容性拉满,适合大多数场景。
方案二:扩展yauzl,手动处理Deflate64解压
如果不想依赖外部工具,可以用deflate64库配合yauzl,手动处理压缩方法9的文件。
- 安装依赖:
npm install yauzl deflate64
- 修改原有yauzl代码:
const yauzl = require('yauzl'); const path = require('path'); const fs = require('fs'); const deflate64 = require('deflate64'); exports.unzip = function (zipPath, targetDir, completeHandler, progressHandler, errHandler) { fs.mkdirSync(targetDir, { recursive: true }); yauzl.open(zipPath, { lazyEntries: true }, (err, zipfile) => { if (err) { errHandler?.(err); return; } zipfile.readEntry(); zipfile.on('entry', (entry) => { const fileDir = path.join(targetDir, entry.fileName); if (/\/$/.test(entry.fileName)) { // 创建目录 fs.mkdirSync(fileDir, { recursive: true }); zipfile.readEntry(); } else { // 关闭自动解压,手动处理原始数据流 zipfile.openReadStream(entry, { decompress: false }, (err, readStream) => { if (err) { // 捕获Deflate64不支持的错误 if (err.message.includes('unsupported compression method: 9')) { const chunks = []; readStream.on('data', (chunk) => chunks.push(chunk)); readStream.on('end', () => { try { // 用deflate64解压数据 const decompressedBuffer = deflate64.decompress(Buffer.concat(chunks)); fs.writeFileSync(fileDir, decompressedBuffer); zipfile.readEntry(); progressHandler?.(/* 可根据已处理文件数计算进度 */); } catch (decompressErr) { errHandler?.(decompressErr); } }); readStream.on('error', (streamErr) => errHandler?.(streamErr)); } else { errHandler?.(err); } return; } // 常规压缩格式直接管道写入 const writeStream = fs.createWriteStream(fileDir); readStream.pipe(writeStream); readStream.on('end', () => { zipfile.readEntry(); progressHandler?.(/* 计算进度 */); }); writeStream.on('error', (writeErr) => errHandler?.(writeErr)); }); } }); zipfile.on('end', () => { console.log('Extraction completed.'); completeHandler?.(); }); zipfile.on('error', (zipErr) => errHandler?.(zipErr)); }); };
注意:这个方案需要手动处理数据流拼接,大文件场景建议优化为流式解压,避免内存占用过高。
内容的提问来源于stack exchange,提问作者Christo c
相关产品推荐
相关产品推荐

