Node.jts का उपयोग करके पूरी निर्देशिका को ज़िप करने की आवश्यकता है


108

मुझे Node.js. का उपयोग करके पूरी निर्देशिका को ज़िप करने की आवश्यकता है मैं वर्तमान में नोड-ज़िप का उपयोग कर रहा हूं और हर बार जब यह प्रक्रिया चलती है तो एक अमान्य ज़िप फ़ाइल उत्पन्न होती है (जैसा कि आप इस गितुब मुद्दे से देख सकते हैं )।

क्या कोई अन्य, बेहतर, Node.js विकल्प है जो मुझे एक निर्देशिका को ज़िप करने की अनुमति देगा?

संपादित करें: मैं अभिलेखागार का उपयोग कर समाप्त हुआ

writeZip = function(dir,name) {
var zip = new JSZip(),
    code = zip.folder(dir),
    output = zip.generate(),
    filename = ['jsd-',name,'.zip'].join('');

fs.writeFileSync(baseDir + filename, output);
console.log('creating ' + filename);
};

मापदंडों के लिए नमूना मूल्य:

dir = /tmp/jsd-<randomstring>/
name = <randomstring>

अद्यतन: मेरे द्वारा उपयोग किए जाने वाले कार्यान्वयन के बारे में पूछने वालों के लिए, यहाँ मेरे डाउनलोडर का लिंक दिया गया है :


3
ट्विटर पर किसी ने child_process एपीआई का सुझाव दिया, और बस प्रणाली ज़िप फोन: nodejs.org/api/child_process.html
commadelimited

1
मैंने child_process दृष्टिकोण की कोशिश की है। इसे दो कैविएट मिले हैं। 1) यूनिक्स zipकमांड में ज़िप्ड फ़ाइल में वर्तमान वर्किंग डायरेक्टरी के सभी पैरेंट फोल्डर पदानुक्रम शामिल हैं। यह आपके लिए ठीक हो सकता है, यह मेरे लिए नहीं था। चाइल्ड_प्रोसेस में वर्तमान कामकाजी निर्देशिका को बदलने से परिणाम प्रभावित नहीं होता है। 2) इस समस्या को दूर करने के लिए, आपको pushdउस फ़ोल्डर में कूदने के लिए उपयोग करना होगा जिसे आप ज़िप करेंगे और zip -rलेकिन चूंकि pushd इसे bash में बनाया गया है और न कि बिन / श के लिए आपको / बिन / bash का भी उपयोग करने की आवश्यकता है। मेरे विशिष्ट मामले में यह संभव नहीं था। बिलकुल चौकन्ना।
जॉन्जॉबाय

2
@johnozbay नोड का child_process.execएपि आपको उस कमांड को निर्दिष्ट करने देता है जहां से आप कमांड चलाना चाहते हैं। CWD को बदलने से पैरेंट फ़ोल्डर पदानुक्रम की समस्या ठीक हो जाती है। यह जरूरत न होने के मुद्दे को भी ठीक करता है pushd। मैं पूरी तरह से child_process की सलाह देता हूं।
गोविंद राय

1
stackoverflow.com/a/49970368/2757916 देशी नोडज समाधान child_process एपीआई का उपयोग कर। कोड की 2 लाइनें। कोई तीसरा पक्ष परिवाद नहीं करता।
गोविंद राय

@ गोविंदराय बहुत धन्यवाद!
जॉनोज़बाय

जवाबों:


127

मैंने अभिलेखागार का उपयोग करके समाप्त कर दिया । बहुत अच्छा काम करता है।

उदाहरण

var file_system = require('fs');
var archiver = require('archiver');

var output = file_system.createWriteStream('target.zip');
var archive = archiver('zip');

output.on('close', function () {
    console.log(archive.pointer() + ' total bytes');
    console.log('archiver has been finalized and the output file descriptor has closed.');
});

archive.on('error', function(err){
    throw err;
});

archive.pipe(output);

// append files from a sub-directory and naming it `new-subdir` within the archive (see docs for more options):
archive.directory(source_dir, false);
archive.finalize();

1
ऐसा करने का कोई उदाहरण नहीं दिखता है, क्या आपने जो किया उसे साझा करने में कोई आपत्ति नहीं है?
सिनहेटा

1
अभिलेखागार, दुर्भाग्य से, अब तक फ़ाइल नाम में यूनिकोड वर्णों का समर्थन नहीं करता है। Github.com/ctalkington/node-archiver/issues/90 पर रिपोर्ट किया गया ।
आई।

2
मैं सभी फ़ाइलों और निर्देशिकाओं को कैसे शामिल कर सकता हूं, पुनरावर्ती (छिपी हुई फाइलें / निर्देशिकाएं)?
Ionică Bizău

12
अभिलेखागार अब इसे और भी सरल बनाता है। बल्क () पद्धति का उपयोग करने के बजाय, अब आप निर्देशिका (): npmjs.com/package/archiver#directory-dirpath-destpath-data
जोश फेल्डमैन

14
.bulkपदावनत है
चोवी

48

मैं कुछ नया दिखाने का दिखावा नहीं करता, बस उन लोगों के लिए उपरोक्त समाधानों को संक्षेप में प्रस्तुत करना चाहता हूं जो अपने कोड (जैसे मेरे) में प्रोमिस फ़ंक्शंस का उपयोग करना पसंद करते हैं।

const archiver = require('archiver');

/**
 * @param {String} source
 * @param {String} out
 * @returns {Promise}
 */
function zipDirectory(source, out) {
  const archive = archiver('zip', { zlib: { level: 9 }});
  const stream = fs.createWriteStream(out);

  return new Promise((resolve, reject) => {
    archive
      .directory(source, false)
      .on('error', err => reject(err))
      .pipe(stream)
    ;

    stream.on('close', () => resolve());
    archive.finalize();
  });
}

आशा है कि यह किसी की मदद करेगा;)


यहाँ वास्तव में "आउट" क्या है? मुझे लगता है कि स्रोत निर्देशिका का रास्ता है
ड्रीम्स

@ तरुण पूर्ण ज़िप का रास्ता जैसे: /User/mypc/mydir/test.zip
D.Dimitrioglo

ज़िप फ़ाइल को अनज़िप नहीं किया जा सकता। ऑपरेशन की अनुमति नहीं है
जेक

@ ekaj_03 कृपया यह सुनिश्चित करें कि आपके पास निर्दिष्ट निर्देशिका के लिए पर्याप्त अधिकार हैं
D.Dimitrioglo

1
@ D.Dimitrioglo सब अच्छा है। यह सोर्स डायर मुद्दा था। धन्यवाद :)
जेक

17

child_processइसे पूरा करने के लिए नोड की देशी एपीआई का उपयोग करें।

थर्ड पार्टी लिबास की जरूरत नहीं। कोड की दो लाइनें।

const child_process = require("child_process");
child_process.execSync(`zip -r DESIRED_NAME_OF_ZIP_FILE_HERE *`, {
  cwd: PATH_TO_FOLDER_YOU_WANT_ZIPPED_HERE
});

मैं सिंक्रोनस एपीआई का उपयोग कर रहा हूं। child_process.exec(path, options, callback)यदि आपको async की आवश्यकता है तो आप इसका उपयोग कर सकते हैं । आपके अनुरोधों को आगे बढ़ाने के लिए CWD को निर्दिष्ट करने की तुलना में बहुत अधिक विकल्प हैं। निष्पादित / निष्पादित करें देखें डॉक्स।


कृपया ध्यान दें: यह उदाहरण मानता है कि आपके सिस्टम पर जिप उपयोगिता स्थापित है (यह OSX के साथ आता है, कम से कम)। कुछ ऑपरेटिंग सिस्टम में उपयोगिता स्थापित नहीं हो सकती (यानी, AWS लैंबडा रनटाइम नहीं है)। उस स्थिति में, आप आसानी से ज़िप उपयोगिता बाइनरी यहाँ प्राप्त कर सकते हैं और इसे अपने आवेदन स्रोत कोड के साथ पैकेज कर सकते हैं (AWS लैम्ब्डा के लिए आप इसे लैम्बडा लेयर में भी पैकेज कर सकते हैं), या आपको किसी तीसरे पक्ष के मॉड्यूल का उपयोग करना होगा (जिनमें एनपीएम पर बहुत सारे हैं)। मैं पूर्व दृष्टिकोण को पसंद करता हूं, क्योंकि ज़िप उपयोगिता की कोशिश की जाती है और दशकों तक परीक्षण किया जाता है।


10
दुर्भाग्य से केवल उन प्रणालियों पर काम करता है जो हैं zip
जंपीओ

3
मेरी परियोजना पर दर्जनों बाहरी पुस्तकालयों से बचने के लिए बस इस समाधान के लिए चला गया
ईज़ेवेदो

यह समझ में आता है, लेकिन अगर मैं गलत नहीं हूँ यह फिर से विंडोज़ उपयोगकर्ताओं पर पंगा लेना है। कृपया विंडोज़ उपयोगकर्ताओं के बारे में सोचें!
मथिजर्स

@MathijsSegers हाहा! यही कारण है कि मैं बाइनरी के लिए एक लिंक शामिल करता हूं ताकि विंडोज़ उपयोगकर्ता इसे भी प्राप्त कर सकें! :)
गोविंद राय

क्या कंप्यूटर निर्देशिका के बजाय परियोजना के भीतर निर्देशिका के लिए काम करने के लिए इसे प्राप्त करने का एक तरीका है?
मैट क्रुक

13

Archive.bulkअब पदावनत किया जाता है, इसके लिए प्रयोग की जाने वाली नई विधि ग्लोब है :

var fileName =   'zipOutput.zip'
var fileOutput = fs.createWriteStream(fileName);

fileOutput.on('close', function () {
    console.log(archive.pointer() + ' total bytes');
    console.log('archiver has been finalized and the output file descriptor has closed.');
});

archive.pipe(fileOutput);
archive.glob("../dist/**/*"); //some glob pattern here
archive.glob("../dist/.htaccess"); //another glob pattern
// add as many as you like
archive.on('error', function(err){
    throw err;
});
archive.finalize();

2
इस बारे में सोच रहा था, उन्होंने कहा कि थोक को हटा दिया गया था लेकिन सुझाव नहीं दिया गया था कि इसके बजाय किस फ़ंक्शन का उपयोग करना है।
मरोड़

1
आप "स्रोत" निर्देशिका को कैसे निर्दिष्ट करते हैं?
सपने

एक बार नीचे दिए गए दृष्टिकोण की कोशिश करें: jsonworld.wordpress.com/2019/09/07/…
सोनी कुमारी

2020: आर्काइव.निर्माता () बहुत सरल है!
OhadR

9

सभी फ़ाइलों और निर्देशिकाओं को शामिल करने के लिए:

archive.bulk([
  {
    expand: true,
    cwd: "temp/freewheel-bvi-120",
    src: ["**/*"],
    dot: true
  }
]);

यह नोड-ग्लोब ( https://github.com/isaacs/node-glob ) का उपयोग करता है, इसलिए इसके साथ संगत कोई भी मिलान अभिव्यक्ति काम करेगी।


.बुलक को पदावनत किया गया है
मोहम्मद हमदउद

9

यह एक अन्य लाइब्रेरी है जो फ़ोल्डर को एक लाइन में ज़िप करता है: ज़िप-लोकल

var zipper = require('zip-local');

zipper.sync.zip("./hello/world/").compress().save("pack.zip");

4
एक आकर्षण की तरह काम किया, इंटरनेट पर उपलब्ध दूसरों के दर्जन के विपरीत या ऊपर उल्लेख किया है, जो हमेशा मेरे लिए 'जीरो बाइट्स' फ़ाइल उत्पन्न करता है
सर्गेई प्लाशेकोव

4

प्रतिक्रिया ऑब्जेक्ट (परिदृश्य जहां स्थानीय रूप से स्टोर करने के बजाय ज़िप डाउनलोड करने की आवश्यकता है) के परिणाम को पाइप करने के लिए)

 archive.pipe(res);

निर्देशिका की सामग्री तक पहुँचने के लिए सैम के संकेत मेरे लिए काम करते थे।

src: ["**/*"]

3

Adm-zip में मौजूदा संग्रह https://github.com/cthackers/adm-zip/ues/64 को संक्षिप्त करने में समस्याएँ हैं साथ-साथ द्विआधारी फ़ाइलों को संपीड़ित करने के साथ भ्रष्टाचार को कम ।

मैं नोड-ज़िप https://github.com/daraosn/node-zip/issues/4 के साथ संपीड़न भ्रष्टाचार के मुद्दों में भी भाग गया हूँ

नोड-आर्काइवर एकमात्र ऐसा है जो संपीड़ित करने के लिए अच्छी तरह से काम करता है, लेकिन इसमें कोई भी असंगत कार्यक्षमता नहीं है।


1
आप किस नोड-आर्काइव के बारे में बात कर रहे हैं? : github.com/archiverjs/node-archiver; github.com/richardbolt/node-archiver
biphobe

@ फ़िरियन उन्होंने आर्किवर नहीं कहा, उन्होंने कहा एडम-जिप।
फ्रांसिस पेलैंड

5
@FrancisPelland उम्म, आखिरी वाक्य में उन्होंने लिखा है " नोड-आर्काइवर एकमात्र ऐसा काम है जो काम करने लगता है " - यही मैं उल्लेख कर रहा हूं।
बीफोबे

मुझे लगता है कि वह meatn npmjs.com/package/archiver
OhadR

2

मुझे यह छोटी सी लाइब्रेरी मिली है जो आपकी ज़रूरतों को पूरा करती है।

npm install zip-a-folder

const zip-a-folder = require('zip-a-folder');
await zip-a-folder.zip('/path/to/the/folder', '/path/to/archive.zip');

https://www.npmjs.com/package/zip-a-folder


क्या ज़िप फ़ोल्डर बनाने के लिए पैरामीटर जोड़ना संभव है? संकुचित स्तर और आकार की तरह अगर ऐसा कैसे करना है?
ट्रांग डी

1

चूंकि archiverलंबे समय से वेबपैक के नए संस्करण के साथ संगत नहीं है, मैं ज़िप-लिब का उपयोग करने की सलाह देता हूं ।

var zl = require("zip-lib");

zl.archiveFolder("path/to/folder", "path/to/target.zip").then(function () {
    console.log("done");
}, function (err) {
    console.log(err);
});

0

आप एक सरल तरीके से कोशिश कर सकते हैं:

स्थापित करें zip-dir:

npm install zip-dir

और इसका उपयोग करें

var zipdir = require('zip-dir');

let foldername =  src_path.split('/').pop() 
    zipdir(<<src_path>>, { saveTo: 'demo.zip' }, function (err, buffer) {

    });

क्या ज़िप फ़ोल्डर बनाने के लिए पैरामीटर जोड़ना संभव है? संकुचित स्तर और आकार की तरह अगर ऐसा कैसे करना है?
ट्रांग डी

0

मैंने JSZip का अनुकरण करने के लिए अभिलेखीय लपेटन को समाप्त कर दिया, क्योंकि मेरी परियोजना के माध्यम से रिफ्लक्टिंग बहुत अधिक प्रयास करता है। मुझे लगता है कि आर्काइवर सबसे अच्छा विकल्प नहीं हो सकता है, लेकिन यहां आप जाते हैं।

// USAGE:
const zip=JSZipStream.to(myFileLocation)
    .onDone(()=>{})
    .onError(()=>{});

zip.file('something.txt','My content');
zip.folder('myfolder').file('something-inFolder.txt','My content');
zip.finalize();

// NodeJS file content:
    var fs = require('fs');
    var path = require('path');
    var archiver = require('archiver');

  function zipper(archive, settings) {
    return {
        output: null,
        streamToFile(dir) {
            const output = fs.createWriteStream(dir);
            this.output = output;
            archive.pipe(output);

            return this;
        },
        file(location, content) {
            if (settings.location) {
                location = path.join(settings.location, location);
            }
            archive.append(content, { name: location });
            return this;
        },
        folder(location) {
            if (settings.location) {
                location = path.join(settings.location, location);
            }
            return zipper(archive, { location: location });
        },
        finalize() {
            archive.finalize();
            return this;
        },
        onDone(method) {
            this.output.on('close', method);
            return this;
        },
        onError(method) {
            this.output.on('error', method);
            return this;
        }
    };
}

exports.JSzipStream = {
    to(destination) {
        console.log('stream to',destination)
        const archive = archiver('zip', {
            zlib: { level: 9 } // Sets the compression level.
        });
        return zipper(archive, {}).streamToFile(destination);
    }
};
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.