如何使用Node.js从tar.gz归档文件中提取单个文件

9
var targz = require('tar.gz');
var extract = new targz().extract(targzFile , destnDir, function(err){
if(err)
     console.log(err);
console.log('The extraction has ended :'+counter);
});

上述代码将targzFile解压到destnDir,然而我想从targzFile中提取单个文件。
提前感谢。

看起来你在node-tar.gz的源代码中没有该选项。请查看从第68行开始的代码以了解.extract的具体情况。 - Matthew Bakaitis
3个回答

14

对于任何对答案感兴趣的人,可以使用流和模块tar-stream实现。以下是一个完整的示例,从存档文件archive.tar.gz中提取名为documents.json的文件:

var tar = require('tar-stream');
var fs = require('fs');
var zlib = require('zlib');

var extract = tar.extract();
var data = '';

extract.on('entry', function(header, stream, cb) {
    stream.on('data', function(chunk) {
    if (header.name == 'documents.json')
        data += chunk;
    });

    stream.on('end', function() {
        cb();
    });

    stream.resume();
});

extract.on('finish', function() {
    fs.writeFile('documents.json', data);
});

fs.createReadStream('archive.tar.gz')
    .pipe(zlib.createGunzip())
    .pipe(extract);

1
在读取条目之前,请检查其是否为文件:header.type === 'file' - Finesse
1
你可以跳过不需要读取的文件。在 entry 回调函数的开头处输入以下代码:if (header.name !== 'document.json') { stream.resume(); sb() },并从 data 回调函数中删除名称检查。 - Finesse
1
应该处理文件读取错误。在 stream.resume() 之前添加以下代码:stream.on('error', cb) - Finesse

3

这篇文章虽然有些旧,但是Gianni的解决方法并不完全适用于我,可能是因为他正在提取文本文件,我不太确定。

此外,你可以通过仅在每个文件记录中一次性检查标题名称而不是针对每个数据块进行优化。

var tar = require('tar-stream');
var fs = require('fs');
var zlib = require('zlib');

var extract = tar.extract();
var chunks = [];

extract.on('entry', function(header, stream, next) {
    if (header.name == 'documents.bin') {
        stream.on('data', function(chunk) {
            chunks.push(chunk);
        });
    }

    stream.on('end', function() {
        next();
    });

    stream.resume();
});

extract.on('finish', function() {
    if (chunks.length) {
        var data = Buffer.concat(chunks);
        fs.writeFile('documents.bin', data);
    }
});

fs.createReadStream('archive.tar.gz')
    .pipe(zlib.createGunzip())
    .pipe(extract);

-2
这个简单的代码片段对我很有效,可以将zipped.tgz解压到downloaded.json中:
const fs = require('fs');
const zlib = require('zlib');

const os = fs.createWriteStream('downloaded.json');
fs.createReadStream('zipped.tgz')
        .pipe(zlib.createGunzip())
        .pipe(os);

该代码片段假定 downloaded.json 文件已被压缩为 gzip 格式(而不是 tar 格式),并且错误地重命名为 zipped.tgz。.tar.gz 之所以被称为 tar 和 gz,是因为它首先将文件与一些元数据连接起来构建存档文件,这会产生一个 .tar 文件。然后将该文件作为单个文件进行压缩,所有的 tar 文件都被视为单个文件并进行压缩,从而添加了 .gz 扩展名。 - Matthias Hryniszak
这个片段假设downloaded.json文件是被gzip压缩(而不是tar压缩),然后错误地重命名为zipped.tgz。一个.tar.gz不是无缘无故地被称为tar和gz的。首先,存档只是将文件和一些元数据连接在一起。这产生了一个.tar文件。然后将文件压缩为一个单独的文件。所有tar压缩的文件都被视为一个单一的文件并进行压缩,这就添加了.gz扩展名。 - undefined

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