将存储为JavaScript缓冲区的未压缩和未GZip文件解压缩

3
我正在开发一个基于Node.js / Express.js的服务器脚本,用于接收包含多个文件的.tar.gz存档。该脚本必须解压缩存档中的CSV文件,并对其进行解析并将一些内容存储在数据库中。不需要将文件存储在服务器上,只需处理它们。为了上传文件,我使用Multer而没有指定存储文件的位置,因此文件上传仅在req.files中作为Buffer可用。
我的问题是,如何解压缩缓冲区并获取文件内容? 如果我执行以下操作:
const { unzipSync } = require('zlib');

const zipped = req.files[0];
const result = await unzipSync(zipped.buffer);
const str = result.toString('utf-8');

我不仅可以提供文件的内容,还能将文件名和元数据等全部信息以字符串形式返回,这使得解析变得棘手。是否有更好的方法?

为什么不使用实际的 tar,然后使用 execspawn 从磁盘加载结果数据呢? - Mike 'Pomax' Kamermans
是的,甚至可以使用Node的tar模块更容易,例如https://www.npmjs.com/package/tar。我只是在想是否可以避免将上传保存到磁盘并从缓冲区解压缩。 - Alex Tok
如果你想解压tgz文件,你需要同时进行解压缩和解打包。现在你只是在解压缩。 - Mike 'Pomax' Kamermans
是的。但是如何在JavaScript中解压缩缓冲区?我找到了许多模块,但没有这样的功能。它们大多使用文件系统中的文件或读取流。 - Alex Tok
你可以链接到一个能够满足你需求的库,但是你找不到具体的细节,所以:你可能想要在他们的问题跟踪器上请求文档记录如何完成该操作。这样,开源社区中的每个人都会受益。 - Mike 'Pomax' Kamermans
1个回答

6

我使用tar-streamstreamifier库成功解压了Buffer。

const tar = require('tar-stream');
const streamifier = require('streamifier');
const { unzipSync } = require('zlib');

const untar = ({ buffer }) => new Promise((resolve, reject) => {
  // Buffer is representation of .tar.gz file uploaded to Express.js server
  // using Multer middleware with MemoryStorage
  const textData = [];
  const extract = tar.extract();
  // Extract method accepts each tarred file as entry, separating header and stream of contents:
  extract.on('entry', (header, stream, next) => {
    const chunks = [];
    stream.on('data', (chunk) => {
      chunks.push(chunk);
    });
    stream.on('error', (err) => {
      reject(err);
    });
    stream.on('end', () => {
      // We concatenate chunks of the stream into string and push it to array, which holds contents of each file in .tar.gz:
      const text = Buffer.concat(chunks).toString('utf8');
      textData.push(text);
      next();
    });
    stream.resume();
  });
  extract.on('finish', () => {
    // We return array of tarred files's contents:
    resolve(textData);
  });
  // We unzip buffer and convert it to Readable Stream and then pass to tar-stream's extract method:
  streamifier.createReadStream(unzipSync(buffer)).pipe(extract);
});

使用这种方法,我成功地避免了在文件系统上存储任何临时文件,并且完全在内存中处理所有文件内容。


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