Node.js में फाइल करने के लिए निर्देशिका बनाते समय


134

मैं Node.js के साथ छेड़छाड़ कर रहा हूं और थोड़ी समस्या पाई है। मुझे एक स्क्रिप्ट मिली है, जिसे निर्देशिका में कहा जाता है data। मैं स्क्रिप्ट को उपनिर्देशिका के भीतर एक उपनिर्देशिका में एक फ़ाइल में कुछ डेटा लिखने के लिए चाहता हूं data। हालाँकि मुझे निम्न त्रुटि मिल रही है:

{ [Error: ENOENT, open 'D:\data\tmp\test.txt'] errno: 34, code: 'ENOENT', path: 'D:\\data\\tmp\\test.txt' }

कोड इस प्रकार है:

var fs = require('fs');
fs.writeFile("tmp/test.txt", "Hey there!", function(err) {
    if(err) {
        console.log(err);
    } else {
        console.log("The file was saved!");
    }
}); 

क्या कोई यह पता लगाने में मेरी मदद कर सकता है कि यदि फाइल में लिखने के लिए यह बाहर नहीं निकलता है तो Node.js निर्देशिका संरचना कैसे बना सकता है?


1
fs.promises.mkdir(path.dirname("tmp/test.txt"), {recursive: true}).then(x => fs.promises.writeFile("tmp/test.txt", "Hey there!"))
ऑफेंसो

जवाबों:


127

नोड> 10.12.0

fs.mkdir अब एक { recursive: true }विकल्प स्वीकार करता है जैसे:

// Creates /tmp/a/apple, regardless of whether `/tmp` and /tmp/a exist.
fs.mkdir('/tmp/a/apple', { recursive: true }, (err) => {
  if (err) throw err;
});

या एक वादा के साथ:

fs.promises.mkdir('/tmp/a/apple', { recursive: true }).catch(console.error);

नोड <= 10.11.0

आप इसे mkdirp या fs-extra जैसे पैकेज के साथ हल कर सकते हैं । यदि आप एक पैकेज स्थापित नहीं करना चाहते हैं, तो कृपया नीचे टियागो पेरेस फ्रांसा का जवाब देखें।


4
वह वही है जिसके साथ मैं जा रहा हूँ ... उन आँकड़ों ने मुझे जीत लिया।
अरन मुल्होलैंड 12

ध्यान दें कि fs.promisesअभी भी प्रायोगिक nodejs.org/dist/latest-v10.x/docs/api/…
Lasec0203

132

यदि आप किसी अतिरिक्त पैकेज का उपयोग नहीं करना चाहते हैं, तो आप अपनी फ़ाइल बनाने से पहले निम्न फ़ंक्शन को कॉल कर सकते हैं:

var path = require('path'),
    fs = require('fs');

function ensureDirectoryExistence(filePath) {
  var dirname = path.dirname(filePath);
  if (fs.existsSync(dirname)) {
    return true;
  }
  ensureDirectoryExistence(dirname);
  fs.mkdirSync(dirname);
}

2
इसके statSyncबजाय इसका उपयोग करना चाहिए existsSync, stackoverflow.com/questions/4482686/…
GavinR

1
pathयह भी एक पैकेज है कि आवश्यकता के रूप में की जरूरत है fs: var path = require('path')मामले में किसी को भी सोच रहा है। नोड प्रलेखन देखें ।
राफेल एम्सहॉफ़

9
fs.existsSyncहै पदावनत , केवल fs.existsहै।
zzzzBov 20

6
फ़ंक्शन fs.existsSync को पदावनत किया गया है या नहीं, इसके बारे में कुछ भ्रम है। सबसे पहले, मेरी समझ से, मुझे लगा कि यह है, इसलिए मैंने इसे प्रतिबिंबित करने के लिए उत्तर अपडेट किया। लेकिन अब, जैसा कि @zzzzBov द्वारा बताया गया है, प्रलेखन में स्पष्ट रूप से कहा गया है कि केवल fs.exists को हटा दिया गया है, fs.existsSync का उपयोग अभी भी मान्य है। इस कारण से मैंने पिछला कोड हटा दिया है और मेरे उत्तर में अब केवल सरल समाधान (fs.existsSync के उपयोग के साथ) है।
टियागो पेर्स फ्रांका

1
@chrismarx निम्नलिखित पथ की कल्पना करता है: "/home/documents/a/b/c/myfile.txt"। "" घर / दस्तावेज "मौजूद है, जबकि इसके सामने सब कुछ नहीं है। जब "ensDirectoryExistence" को पहली बार कहा जाता है, तो dirname "/ home / documents / a / b /" है। मैं अभी fs.mkdirSync (dirname) को कॉल नहीं कर सकता क्योंकि "/ होम / दस्तावेज़ / a / b" भी मौजूद नहीं है। निर्देशिका "सी" बनाने के लिए, मुझे पहले "/ घर / दस्तावेजों / ए / बी" के अस्तित्व को सुनिश्चित करने की आवश्यकता है।
टिआगो पेर्स फ्रांका

43

साथ नोड FS-अतिरिक्त आप इसे आसानी से कर सकते हैं।

इसे स्थापित करो

npm install --save fs-extra

फिर outputFileविधि का उपयोग करें । इसका प्रलेखन कहता है:

लगभग वैसा ही जैसा कि राइटफाइल (यानी यह ओवरराइट हो जाता है), सिवाय इसके कि अगर मूल निर्देशिका मौजूद नहीं है, तो इसे बनाया जाता है।

आप इसे तीन तरीकों से उपयोग कर सकते हैं:

कॉलबैक शैली

const fse = require('fs-extra');

fse.outputFile('tmp/test.txt', 'Hey there!', err => {
  if(err) {
    console.log(err);
  } else {
    console.log('The file was saved!');
  }
})

वादे का उपयोग करना

यदि आप वादों का उपयोग करते हैं , और मुझे आशा है कि यह कोड है:

fse.outputFile('tmp/test.txt', 'Hey there!')
   .then(() => {
       console.log('The file was saved!');
   })
   .catch(err => {
       console.error(err)
   });

सिंक संस्करण

यदि आप एक सिंक संस्करण चाहते हैं, तो बस इस कोड का उपयोग करें:

fse.outputFileSync('tmp/test.txt', 'Hey there!')

एक संपूर्ण संदर्भ के लिए, outputFileदस्तावेज़ीकरण और सभी नोड-एफएस-अतिरिक्त समर्थित तरीकों की जांच करें


26

बेशर्म प्लग अलर्ट!

यदि आप चाहते हैं कि पथ संरचना में प्रत्येक निर्देशिका के लिए आपको जाँच करनी होगी और यदि यह मौजूद नहीं है तो इसे मैन्युअल रूप से बनाएं। ऐसा करने के सभी उपकरण पहले से ही नोड के fs मॉड्यूल में हैं, लेकिन आप मेरे mkpath मॉड्यूल के साथ बस इतना ही कर सकते हैं: https://github.com/jrajav/mkpath


1
क्या वह फ़ाइल सीधे या केवल निर्देशिका संरचना बना देगा? मैं एक समाधान की तलाश कर रहा हूं, जो फ़ाइल बनाते समय निर्देशिका संरचना के साथ फ़ाइल बनाएं।
हिरवेश

बस निर्देशिका संरचना। आप mkdir / पथ पहले और, अगर कोई त्रुटि नहीं थी, अपनी फ़ाइल लिखने के लिए आगे बढ़ें। यह काफी सरल होगा कि दोनों को एक साथ करने के लिए एक फ़ंक्शन लिखने के लिए, एक फ़ाइल को लिखने के लिए एक पूर्ण पथ दिया गया है - बस पथ का उपयोग करके फ़ाइल नाम को अलग कर दें। नामसेन
jrajav

1
वास्तव में, यह इतना सरल था कि मैंने इसे 2 मिनट में लिखा था । :) (
अछूता

अद्यतन: परीक्षण किया गया और संपादित किया गया, कृपया इसे फिर से आज़माएँ यदि यह पहली बार काम नहीं किया।
jrajav

8
@Kiyura यह व्यापक रूप से इस्तेमाल किए जाने वाले mkdirp से कैसे अलग है ?
डेविड वेल्डन

9

चूँकि मैं अभी तक कोई टिप्पणी नहीं कर सकता, इसलिए मैं @ tiago-peres-frança शानदार समाधान (धन्यवाद) के आधार पर एक विस्तारित उत्तर पोस्ट कर रहा हूं। उसका कोड उस मामले में निर्देशिका नहीं बनाता है, जहां पथ में केवल अंतिम निर्देशिका गायब है, उदाहरण के लिए इनपुट "C: / test / abc" और "C: / test" पहले से मौजूद है। यहाँ एक स्निपेट है जो काम करता है:

function mkdirp(filepath) {
    var dirname = path.dirname(filepath);

    if (!fs.existsSync(dirname)) {
        mkdirp(dirname);
    }

    fs.mkdirSync(filepath);
}

1
ऐसा इसलिए है क्योंकि @ टियागो का समाधान एक फ़ाइल पथ की अपेक्षा करता है। आपके मामले में, abcउस फ़ाइल के रूप में व्याख्या की गई है जिसके लिए आपको एक निर्देशिका बनाने की आवश्यकता है। abcनिर्देशिका बनाने के लिए , अपने पथ पर एक डमी फ़ाइल जोड़ें, जैसे C:/test/abc/dummy.txt
स्फिंक्सएक्स

पुनरावर्ती का प्रयोग करें:fs.promises.mkdir(path.dirname(file), {recursive: true}).then(x => fs.promises.writeFile(file, data))
Offenso

1
@ ओफ़ेन्सो यह सबसे अच्छा समाधान है, लेकिन Node.js संस्करण 10.12 और इसके बाद के संस्करण के लिए।
निकोलस

8

मेरी सलाह है: जब आप आसानी से कोड की कुछ पंक्तियों के साथ कर सकते हैं तो निर्भरता पर भरोसा न करें

यहाँ आप कोड की 14 लाइनों को प्राप्त करने का प्रयास कर रहे हैं :

fs.isDir = function(dpath) {
    try {
        return fs.lstatSync(dpath).isDirectory();
    } catch(e) {
        return false;
    }
};
fs.mkdirp = function(dirname) {
    dirname = path.normalize(dirname).split(path.sep);
    dirname.forEach((sdir,index)=>{
        var pathInQuestion = dirname.slice(0,index+1).join(path.sep);
        if((!fs.isDir(pathInQuestion)) && pathInQuestion) fs.mkdirSync(pathInQuestion);
    });
};

1
क्या तीसरी पंक्ति इस तरह बेहतर नहीं होगी? return fs.lstatSync(dpath).isDirectory()अन्यथा, क्या होगा यदि डडायरेक्टरी () गलत रिटर्न देता है?
जियोर्जियो एरेसू

2
पुनरावर्ती का प्रयोग करें:fs.promises.mkdir(path.dirname(file), {recursive: true}).then(x => fs.promises.writeFile(file, data))
Offenso

1
@ ओफ़ेन्सो यह एक नोड 8 द्वारा समर्थित नहीं है
इविगेन नीडा

2

मैंने सिर्फ इस मॉड्यूल को प्रकाशित किया क्योंकि मुझे इस कार्यक्षमता की आवश्यकता थी।

https://www.npmjs.org/package/filendir

यह Node.js fs विधियों के आसपास एक आवरण की तरह काम करता है। तो आप इसका ठीक उसी तरह से उपयोग कर सकते हैं जैसा आप करेंगे fs.writeFileऔर fs.writeFileSync(दोनों async और सिंक्रोनस लिखते हैं)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.