Concat将数据stream式传输到单个文件或string,同时使用Node提取zip文件

我正在使用yauzl节点模块。 我从Zip文件中提取XML文件。 读取条目时,在readSteam.on('data')callback函数中,我将entry.filename及其内容logging为string。 但是,有些文件被分解成多个文件。 这些部分共享相同的fileName 。 每个部分都包含部分文件内容。

  let options = { lazyEntries: true } yauzl.open(params.pathToZip, options, function(err, zipfile) { if(err) throw err zipfile.readEntry() zipfile.on("error", function(err) { throw err }) zipfile.on("entry", function(entry) { if (/\/$/.exec(entry)) return false zipfile.openReadStream(entry, options, (err, readStream) => { if (err) throw err readStream.on('data', data => { console.log(entry.fileName) console.log(data.toString()) }) }) zipfile.readEntry() }); zipfile.once("end", function() { console.log('END EVENT CALLBACK') zipfile.close() }); }); 

是否有内置的方法,将这些string连接(通过知道他们共享相同的文件名)到一个单一的文件或string,然后可以被parsing为一个。

如果使用了substr )方法,例如console.log(data.toString().substr(0,10)) (因为我们只关心每个数据文件的前几个字符以便表示),则日志看起来像这样:

 TH/CJM/CJM00083_en.xml <hotel des TH/CJM/CJM0007V_en.xml <hotel des TH/CJM/CJM0007V_en.xml vel.com/HH TH/CJM/YYY1RHVV_en.xml <hotel des TH/CJM/YYY1RHVV_en.xml om/hotels/ TH/CJM/YYY0DJJ2_en.xml <hotel des TH/CJM/CJM0005P_en.xml <hotel des 

正如日志显示的那样,当数据被分解时,文件名会被重复。

你应该等待'end' 事件被发射:

 zipfile.openReadStream(entry, options, (err, readStream) => { if (err) throw err; var str = ''; readStream.on('data', data => { str += data.toString(); }); readStream.on('end', function() { console.log(entry.fileName); console.log(str); // Next entry... zipfile.readEntry(); }); }); 

您可以创build一个普通对象或Map ,其中属性名称是文件名。 如果属性名称存在且等于当前文件名,则将当前文件的文本连接到对象的属性值,否则创build一个新的属性设置为当前文件名,将属性值设置为文件内容; 重复过程,直到所有文件都被处理完毕。

 if (obj.hasOwnProperty(fileName)) { obj[fileName] += fileContents } else { obj[fileName] = fileContents }