Node.js如何在不解压缩的情况下读取zip文件中的文件?

25

我有一个zip文件(实际上是epub文件),我需要遍历其中的文件并在不将其解压到磁盘的情况下读取它们。

我尝试使用一个名为JSZip 的Node.js库,但每个文件的内容都存储在缓冲区中,并且每当我尝试将缓冲区内容解码为字符串时,返回的内容无法阅读。

这是我尝试过的代码:

const zip = new JSZip();
  // read a zip file
    fs.readFile(epubFile, function (err, data) {
        if (err) throw err;
        zip.loadAsync(data).then(function (zip) {
            async.eachOf(zip.files, function (content, fileName, callback) {
                if (fileName.match(/json/)) {
                    var buf = content._data.compressedContent;
                    console.log(fileName);
                    console.log((new Buffer(buf)).toString('utf-8'));
                }
                callback();
            }, function (err) {
                if (err) {
                    console.log(err);
                }
            });
        });
    });
2个回答

27

由于unzip似乎已被放弃,我使用node-stream-zip并获得了相当不错的成功。

npm install node-stream-zip

读取文件就像这样:

const StreamZip = require('node-stream-zip');
const zip = new StreamZip({
    file: 'archive.zip',
    storeEntries: true
});

zip.on('ready', () => {
    // Take a look at the files
    console.log('Entries read: ' + zip.entriesCount);
    for (const entry of Object.values(zip.entries())) {
        const desc = entry.isDirectory ? 'directory' : `${entry.size} bytes`;
        console.log(`Entry ${entry.name}: ${desc}`);
    }

    // Read a file in memory
    let zipDotTxtContents = zip.entryDataSync('path/inside/zip.txt').toString('utf8');
    console.log("The content of path/inside/zip.txt is: " + zipDotTxtContents);

    // Do not forget to close the file once you're done
    zip.close()
});

10
npm install unzip

https://www.npmjs.com/package/unzip

    fs.createReadStream('path/to/archive.zip')
  .pipe(unzip.Parse())
  .on('entry', function (entry) {
    var fileName = entry.path;
    var type = entry.type; // 'Directory' or 'File' 
    var size = entry.size;
    if (fileName === "this IS the file I'm looking for") {
      entry.pipe(fs.createWriteStream('output/path'));
    } else {
      entry.autodrain();
    }
  });

你要如何使用输入作为读取流?我正在尝试将它传输到 S3。 - Big Money
8
unzip 已经有四年没有更新了。该项目已经停止维护。- https://github.com/EvanOxfeld/node-unzip/issues/81 - Ryan Shillington
我相信@BigMoney现在已经弄清楚了,要将文件传输到S3,您需要在PassThrough流上追加一个额外的管道,并将PassThrough流作为S3的body参数提供。使用Pipeline比在每个流上调用.pipe更为推荐。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接