question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Can finalize be called before entry streams are done?

See original GitHub issue

Ideally, I would think I could add as many entries with streams as I want, then call finalize right afterward and everything would work (ie automatically wait for all the input streams to complete before actually creating the package). The documentation seems to imply that this isn’t the case tho. Can I or can’t i do that? If not, why not? Can we make it so finalize can be called without explicitly waiting for the streams?

Issue Analytics

  • State:open
  • Created 9 years ago
  • Reactions:3
  • Comments:11 (2 by maintainers)

github_iconTop GitHub Comments

12reactions
croqazcommented, Aug 10, 2016

Hey everyone !! Any news about this issue? Adding multiple files within a tar archive would be really useful…

2reactions
abrinckmcommented, Nov 25, 2019

@croqaz @mafintosh @fresheneesz

Hi, I was able to stream multiple entries using the following code and without any modifications to mafintosh’s original source code. This will create a .tar.gz file using only streams:

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

function exampleCreateTarGzip (files) {
    const pack = tar.pack();
    const gzipStream = zlib.createGzip({level: zlib.constants.Z_BEST_COMPRESSION});
    
    // Example list of files
    files = [ { name:"./works.csv", size: 3654 }, { name: "./manuscripts.csv", size: 303156 } ];

    return new Promise((resolve, reject) => {
      pack.on('error', reject);
      
      packEntry();
      
      // Callback is recursive
      function packEntry(err) {
        if (err) {
          reject(err);
        } else if (files.length) {
          const file_entry = files.pop();

          //please note the recursive callback here
          const entry = pack.entry({ name: file_entry.name, size: file_entry.size }, packEntry); 

          const readStream = fs.createReadStream(file_entry.name);

          readStream.on('end', entry.end.bind(entry));     // This is key to getting this to work
          readStream.on('error', reject);
          readStream.pipe(entry);
        } else {
          pack.finalize();
        }
      }

      const writeStream = fs.createWriteStream('./archive.tar.gz');
      writeStream.on('error', reject);
      writeStream.on('end', () => { resolve('Done archiving files'); });

      pack.pipe(gzipStream).pipe(writeStream);
    });
}

The key here is to call pack.entry() only after the previous entry has finished streaming and also to know when to explicitly call entry.end()

This is recursive but perhaps can be done differently. Maybe some tweaks are needed to get this to work properly for you (this was roughly copied and modified from my own code), but this solution works just fine for me.

Read more comments on GitHub >

github_iconTop Results From Across the Web

finalize() called on strongly reachable objects in Java 8
And finalize() doesn't call close() on the stream directly but via its own instance method close() which will then invoke close() on the...
Read more >
A Guide to the finalize Method in Java - Baeldung
The finalize() method is called the finalizer. Finalizers get invoked when JVM figures out that this particular instance should be garbage ...
Read more >
finalize called on strongly reachable object in Java 8 - Edureka
Logging shows that the finalizer thread is calling finalize() on the object that holds the stream (which in turn closes the stream).
Read more >
10 points on finalize method in Java – Tutorial Example
4) finalize gets called only once by GC thread if the object revives itself from the finalize() method then finalize will not be...
Read more >
MET12-J. Do not use finalizers
The Java programming language imposes no ordering on finalize() method calls. Finalizers [of different objects] may be called in any order, ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found