it-swarm.com.de

Wie schreibe ich eine Datei, wenn der übergeordnete Ordner nicht existiert?

Ich muss eine Datei in den folgenden Pfad schreiben:

 fs.writeFile('/folder1/folder2/file.txt', 'content', function () {

 });

Aber '/folder1/folder2' Pfad existiert möglicherweise nicht. So bekomme ich folgenden Fehler:

 message=ENOENT, open /folder1/folder2/file.txt

Wie kann ich Inhalte in diesen Pfad schreiben?

73
Erik

Verwenden Sie mkdirp in Kombination mit path.dirname zuerst.

var mkdirp = require('mkdirp');
var fs = require('fs');
var getDirName = require('path').dirname;

function writeFile(path, contents, cb) {
  mkdirp(getDirName(path), function (err) {
    if (err) return cb(err);

    fs.writeFile(path, contents, cb);
  });
}

Wenn der gesamte Pfad bereits existiert, ist mkdirp ein Noop. Andernfalls werden alle fehlenden Verzeichnisse für Sie erstellt.

Dieses Modul macht was Sie wollen: https://npmjs.org/package/writefile . Habe es beim googeln nach "writefile mkdirp". Dieses Modul gibt ein Versprechen zurück, anstatt einen Rückruf entgegenzunehmen. Lesen Sie daher zunächst eine Einführung zu den Versprechen. Es könnte die Dinge für Sie tatsächlich komplizieren.

Die Funktion, die ich gegeben habe, funktioniert auf jeden Fall.

114
Myrne Stol

Ich finde, dass der einfachste Weg dies zu tun ist, die outputFile () -Methode aus der fs- extra Modul.

Fast dasselbe wie writeFile (d. H. Es überschreibt), außer dass es erstellt wird, wenn das übergeordnete Verzeichnis nicht vorhanden ist. Optionen sind das, was Sie an fs.writeFile () übergeben würden.

Beispiel:

var fs = require('fs-extra');
var file = '/tmp/this/path/does/not/exist/file.txt'

fs.outputFile(file, 'hello!', function (err) {
    console.log(err); // => null

    fs.readFile(file, 'utf8', function (err, data) {
        console.log(data); // => hello!
    });
});

Heutzutage hat es auch eine sofort einsatzbereite Unterstützung zugesagt !.

19
tkarls

Am einfachsten ist es, wenn Sie das fs-path npm-Modul verwenden.

Ihr Code würde dann so aussehen:

var fsPath = require('fs-path');

fsPath.writeFile('/folder1/folder2/file.txt', 'content', function(err){
  if(err) {
    throw err;
  } else {
    console.log('wrote a file like DaVinci drew machines');
  }
});
17
kevincoleman

Bearbeiten

NodeJS Version 10 hat eine native Unterstützung für mkdir und mkdirSync hinzugefügt, um den übergeordneten Director rekursiv mit der Option recursive: true wie folgt zu erstellen:

fs.mkdirSync(targetDir, { recursive: true });

Und wenn Sie fs Promises API bevorzugen, können Sie schreiben

fs.promises.mkdir(targetDir, { recursive: true });

Ursprüngliche Antwort

Erstellen Sie die übergeordneten Verzeichnisse rekursiv, wenn sie nicht vorhanden sind! ( Null Abhängigkeiten )

const fs = require('fs');
const path = require('path');

function mkDirByPathSync(targetDir, { isRelativeToScript = false } = {}) {
  const sep = path.sep;
  const initDir = path.isAbsolute(targetDir) ? sep : '';
  const baseDir = isRelativeToScript ? __dirname : '.';

  return targetDir.split(sep).reduce((parentDir, childDir) => {
    const curDir = path.resolve(baseDir, parentDir, childDir);
    try {
      fs.mkdirSync(curDir);
    } catch (err) {
      if (err.code === 'EEXIST') { // curDir already exists!
        return curDir;
      }

      // To avoid `EISDIR` error on Mac and `EACCES`-->`ENOENT` and `EPERM` on Windows.
      if (err.code === 'ENOENT') { // Throw the original parentDir error on curDir `ENOENT` failure.
        throw new Error(`EACCES: permission denied, mkdir '${parentDir}'`);
      }

      const caughtErr = ['EACCES', 'EPERM', 'EISDIR'].indexOf(err.code) > -1;
      if (!caughtErr || caughtErr && curDir === path.resolve(targetDir)) {
        throw err; // Throw if it's just the last created dir.
      }
    }

    return curDir;
  }, initDir);
}

Verwendung

// Default, make directories relative to current working directory.
mkDirByPathSync('path/to/dir');

// Make directories relative to the current script.
mkDirByPathSync('path/to/dir', {isRelativeToScript: true});

// Make directories with an absolute path.
mkDirByPathSync('/path/to/dir');

Demo

Probieren Sie es aus!

Erklärungen

  • [UPDATE] Diese Lösung behandelt plattformspezifische Fehler wie EISDIR für Mac und EPERM und EACCES für Windows.
  • Diese Lösung behandelt sowohl relative als auch absolute Pfade.
  • Bei relativen Pfaden werden Zielverzeichnisse im aktuellen Arbeitsverzeichnis erstellt (aufgelöst). Übergeben Sie {isRelativeToScript: true}, Um sie relativ zum aktuellen Skriptverzeichnis aufzulösen.
  • Verwenden Sie path.sep und path.resolve() und nicht nur die Verkettung /, Um plattformübergreifende Probleme zu vermeiden.
  • Verwenden von fs.mkdirSync und Behandeln des Fehlers mit try/catch, Wenn die Race-Bedingungen berücksichtigt werden: Ein anderer Prozess kann die Datei zwischen den Aufrufen von fs.existsSync() und fs.mkdirSync() und löst eine Ausnahme aus.
    • Die andere Möglichkeit, dies zu erreichen, besteht darin, zu überprüfen, ob eine Datei vorhanden ist, und sie dann zu erstellen, d. H. if (!fs.existsSync(curDir) fs.mkdirSync(curDir);. Dies ist jedoch ein Anti-Pattern, das den Code anfällig für Rennbedingungen macht.
  • Benötigt Node v6 und neuer zur Unterstützung der Destrukturierung. (Wenn Sie Probleme haben, diese Lösung mit alten Node Versionen zu implementieren, hinterlassen Sie mir einfach einen Kommentar)
7
Mouneer

Sie können verwenden

fs.stat('/folder1/folder2', function(err, stats){ ... });

stats ist ein Objekt vom Typ fs.Stats, Sie können stats.isDirectory() überprüfen. Abhängig von der Prüfung von err und stats können Sie etwas tun, fs.mkdir( ... ) oder einen Fehler auslösen.

Referenz

Update: Die Kommas im Code wurden korrigiert.

3
MikeD

Hier ist meine benutzerdefinierte Funktion zum rekursiven Erstellen von Verzeichnissen (ohne externe Abhängigkeiten):

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

var myMkdirSync = function(dir){
    if (fs.existsSync(dir)){
        return
    }

    try{
        fs.mkdirSync(dir)
    }catch(err){
        if(err.code == 'ENOENT'){
            myMkdirSync(path.dirname(dir)) //create parent dir
            myMkdirSync(dir) //create dir
        }
    }
}

myMkdirSync(path.dirname(filePath));
var file = fs.createWriteStream(filePath);
2
math_lab3.ca

Hier ist meine Funktion, die in Node 10.12.0 funktioniert. Hoffe, das wird helfen.

const fs = require('fs');
function(dir,filename,content){
        fs.promises.mkdir(dir, { recursive: true }).catch(error => { console.error('caught exception : ', error.message); });
        fs.writeFile(dir+filename, content, function (err) {
            if (err) throw err;
            console.info('file saved!');
        });
    }
1
Kailash

Hier ist ein Teil der Antwort von Myrne Stol als separate Antwort:

Dieses Modul macht was Sie wollen: https://npmjs.org/package/writefile . Habe es beim googeln nach "writefile mkdirp". Dieses Modul gibt ein Versprechen zurück, anstatt einen Rückruf entgegenzunehmen. Lesen Sie daher zunächst eine Einführung zu den Versprechen. Es könnte die Dinge für Sie tatsächlich komplizieren.

0
David Braun