javascript - How to create a ZIP file with Gulp that contains a lot of files? -
i have gulp task add lots of files (more 2700 in 1 case, can several thousands in others cases) in zip file. code follow:
const fs = require('fs'); const archiver = require('archiver')('zip'); let zip = fs.createwritestream('my-archive.zip'); return gulp.src('app/**/*') .pipe(through.obj((file, encoding, cb) => { let pathinzip = '...'; if (!isadirectory(file.path)) { // not zip directory archiver.append(fs.createreadstream(file.path), { name: pathinzip, mode: fs.statsync(file.path) }); } cb(null, file); }, cb => { // create zip file! archiver.pipe(zip); archiver.finalize(); cb(); }));
this code works on small projects, when deals more 2000 files, following error:
events.js:154 throw er; // unhandled 'error' event ^ error: emfile: many open files, open 'd:\dev\app\some\file' @ error (native)
so understand having 2000+ files opened @ same time before writing them in zip not idea.
how can ask zip file written without having need open files?
thanks.
for information: node 5.5.0 / npm 3.8.5 / archiver 1.0.0 / windows
gulp takes care of lot of things you're trying do:
gulp.src()
reads file contents , makesfs.stat()
call each file. stores bothfile.contents
,file.stat
onvinyl-file
objects emits.- it using
graceful-fs
package, automatically backs off in case of emfile error , retries when file has closed. prevents "too many open files" problem you're experiencing.
unfortunately you're not taking advantage of of because:
- you're making explicit calls
fs.statsync()
,fs.createreadstream()
. there's no need since gulp has done you. you're reading each file twice (and creating twice number of file descriptors in process). - you're circumventing gulp's built-in protection against emfile making direct use of
fs
module not have guards against "too many open files" problem.
i've rewritten code take advantage of gulp's features. i've tried make little more gulp-idiomatic, e.g. using gulp-filter
rid of directories:
const gulp = require('gulp'); const fs = require('graceful-fs'); const archiver = require('archiver')('zip'); const through = require('through2'); const filter = require('gulp-filter'); gulp.task('default', () => { var zip = fs.createwritestream('my-archive.zip'); archiver.pipe(zip); return gulp.src('app/**/*') .pipe(filter((file) => !file.stat.isdirectory())) .pipe(through.obj((file, encoding, cb) => { var pathinzip = '...'; archiver.append(file.contents, { name: pathinzip, mode: file.stat }); cb(null, file); }, cb => { zip.on('finish', cb); archiver.finalize(); })); });
Comments
Post a Comment