node.js - use archiver where output is buffer

9k views Asked by At

I want to zip a few readeableStreams into a writableStream. the purpose is to do all in memory and not to create an actual zip file on disk.

for that i'm using archiver

        let bufferOutput = Buffer.alloc(5000);
        let archive = archiver('zip', {
            zlib: { level: 9 } // Sets the compression level.
        });
        archive.pipe(bufferOutput);
        archive.append(someReadableStread, { name: test.txt});
        archive.finalize();

I get an error on line archive.pipe(bufferOutput);.

This is the error: "dest.on is not a function"

what am i doing wrong? Thx

UPDATE:

I'm running the following code for testing and the ZIP file is not created properly. what am I missing?

const   fs = require('fs'),
    archiver = require('archiver'),
    streamBuffers = require('stream-buffers');

let outputStreamBuffer = new streamBuffers.WritableStreamBuffer({
    initialSize: (1000 * 1024),   // start at 1000 kilobytes.
    incrementAmount: (1000 * 1024) // grow by 1000 kilobytes each time buffer overflows.
});

let archive = archiver('zip', {
    zlib: { level: 9 } // Sets the compression level.
});
archive.pipe(outputStreamBuffer);

archive.append("this is a test", { name: "test.txt"});
archive.finalize();

outputStreamBuffer.end();

fs.writeFile('output.zip', outputStreamBuffer.getContents(), function() { console.log('done!'); });
4

There are 4 answers

3
Dave Irvine On

As for why you are seeing garbage, this is because what you are seeing is the zipped data, which will seem like garbage.

To verify if the zipping has worked, you probably want to unzip it again and check if the output matches the input.

1
Dave Irvine On

A Buffer is not a stream, you need something like https://www.npmjs.com/package/stream-buffers

0
patmood On

In your updated example, I think you are trying to get the contents before it has been written.

Hook into the finish event and get the contents then.

outputStreamBuffer.on('finish', () => {
  // Do something with the contents here
  outputStreamBuffer.getContents()
})
0
Z Li On

By adding the event listener on archiver works for me:

archive.on('finish', function() {
   outputStreamBuffer.end();
   // write your file
});