我有一个 ReadableStream 未压缩的文本数据,我需要将其存储在 S3 上的单个 zip 压缩文件中。
我不想做的事:
我想做的事:
到目前为止我尝试过的:
import {S3} from 'aws-sdk';
import {PassThrough} from 'stream';
import archiver from 'archiver';
const s3 = new S3({region: 'us-east-1'});
(async () => {
const stream = new PassThrough();
const archive = archiver('zip', {
zlib: { level: 9 }
});
archive.pipe(stream);
const upload = s3.upload({
Bucket: 'my-bucket',
Key: 'stream.zip',
Body: stream,
}).promise();
// Assume this is the readable stream we are reading from
for (let i = 0; i < 100; i++) {
const textData = `text-data-${i}`;
archive.append(Buffer.from(`${textData}\n`, 'utf8'), { name: `file-${i}.txt` });
}
await archive.finalize();
await upload;
})();
这是不正确的,因为它在 S3 上的输出存档
stream.zip
中生成多个文件(file-1.txt
、file-2.txt
等)。另一方面,如果我在将数据附加到archive
时使用单个文件名,则需要在附加之前将所有数据缓冲到内存中,这会抵消增量流数据的目的。
有谁知道这个问题的解决办法吗?
我可能找到了一个解决方案,基本上是将 Stream 而不是 Buffer 附加到存档器:
import {S3} from 'aws-sdk';
import {PassThrough} from 'stream';
import archiver from 'archiver';
const s3 = new S3({region: 'us-east-1'});
(async () => {
const inputStream = new PassThrough();
const outputStream = new PassThrough();
const archive = archiver('zip', {
zlib: { level: 9 }
});
archive.pipe(outputStream);
// Append a stream instead of a Buffer. This should result in a single zipped file.
archive.append(inputStream, {name: 'myfile.txt'});
const upload = s3.upload({
Bucket: 'my-bucket',
Key: 'stream.zip',
Body: outputStream,
}).promise();
for (let i = 0; i < 100; i++) {
const textData = `text-data-${i}\n`;
inputStream.write(textData, 'utf-8');
}
inputStream.end();
await Promise.all([
archive.finalize(),
upload,
]);
outputStream.end();
})();
很高兴听到对此的意见。