Üst klasör yoksa dosya nasıl yazılır?


95

Aşağıdaki yola dosya yazmam gerekiyor:

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

Ancak '/folder1/folder2'yol olmayabilir. Bu yüzden aşağıdaki hatayı alıyorum:

message = ENOENT, /folder1/folder2/file.txt dosyasını aç

Bu yola nasıl içerik yazabilirim?


2
fs.promises.mkdir(path.dirname('/folder1/folder2/file.txt'), {recursive: true}).then(x => fs.promises.writeFile('/folder1/folder2/file.txt', 'content'))
Offenso

Yanıtlar:


133

Mkdirp'ipath.dirname ilk ile birlikte kullanın .

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);
  });
}

Tüm yol zaten varsa, mkdirpnooptur. Aksi takdirde eksik olan tüm dizinleri sizin için oluşturur.

Bu modül istediğinizi yapar: https://npmjs.org/package/writefile . "Writeefile mkdirp" için Google'da arama yaparken anladım. Bu modül, geri arama almak yerine bir söz verir, bu nedenle önce vaatlerin bazılarını okuduğunuzdan emin olun. Aslında işleri sizin için karmaşık hale getirebilir.

Verdiğim işlev her durumda işe yarıyor.


Öyleyse, tamamlanmasını beklemek istiyorsak, ondan sonraki her şeyi geri aramaya koymalı mıyız? Başka bir yolu var mı?
pete

@pete eğer babel kullanırsanız, async ile gidebilirsiniz / şu ana kadar bekleyin: gist.github.com/lucasreppewelander/…
Lucas Reppe Welander

11
Yinelemeli kullanın:fs.promises.mkdir(path.dirname(file), {recursive: true}).then(x => fs.promises.writeFile(file, data))
Offenso

27

Bunu yapmanın en kolay yolunun fs-extra modülünden outputFile () yöntemini kullanmak olduğunu buldum .

WriteFile ile hemen hemen aynıdır (yani üzerine yazar), tek fark, eğer ana dizin yoksa, oluşturulur. seçenekler fs.writeFile () 'ye ileteceğiniz şeylerdir.

Misal:

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!
    });
});

Ayrıca bugünlerde kutudan çıktığı gibi destek sözü veriyor !.


21

Düzenle

NodeJS versiyonu 10.12.0bir yerel destek hem de eklemiştir mkdirve mkdirSyncbirlikte yinelemeli ebeveyn yönetmeni oluşturmak için recursive: trueaşağıdaki gibi seçenek:

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

Ve eğer tercih fs Promises APIedersen yazabilirsin

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

Orijinal Cevap

Eğer yoksa, üst dizinleri tekrar tekrar oluşturun! ( Sıfır bağımlılık )

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);
}

Kullanım

// 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

Dene!

Açıklamalar

  • [GÜNCELLEME] gibi Bu çözüm kolları platforma özel hataları EISDIR, Mac ve EPERMve EACCESWindows için.
  • Bu çözelti, iki işleme göre ve mutlak yolları.
  • Göreli yollar olması durumunda, mevcut çalışma dizininde hedef dizinler oluşturulur (çözülür). Bunları geçerli betik dizinine göre çözmek için, pass {isRelativeToScript: true}.
  • Platformlar arası sorunları önlemek için yalnızca birleştirme değil path.sepve kullanma .path.resolve()/
  • Kullanılması fs.mkdirSyncve hatayı işleme try/catchyarış koşulları ele atılırsa: Başka bir işlem için çağrılar arasında dosya ekleyebilir fs.existsSync()ve fs.mkdirSync()bir duruma neden olur.
    • Bunu başarmanın diğer yolu, bir dosyanın var olup olmadığını kontrol etmek ve sonra onu oluşturmak olabilir, yani if (!fs.existsSync(curDir) fs.mkdirSync(curDir);. Ancak bu, kodu yarış koşullarına karşı savunmasız bırakan bir anti-modeldir.
  • Yıkmayı desteklemek için Node v6 ve daha yenisini gerektirir . (Bu çözümü eski Node sürümleriyle uygularken sorun yaşıyorsanız, bana bir yorum bırakın)

19

Belki de en basit şekilde, sadece fs-path npm modülünü kullanabilirsiniz.

Kodunuz daha sonra şöyle görünecektir:

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');
  }
});

3

Kullanabilirsiniz

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

statsbir fs.Statsnesne türüdür, kontrol edebilirsiniz stats.isDirectory(). İncelenmesine bağlı olarak errve statsbir şeyler yapmak, olabilir fs.mkdir( ... )veya bir hata atmak.

Referans

Güncelleme: Koddaki virgül düzeltildi.


Yani nodejs'de sibgle komutunu kullanarak dosya yazamıyorum?
Erik

3

Node-fs-extra ile bunu kolayca yapabilirsiniz.

Yükle

npm install --save fs-extra

Daha sonra kullanmak ÇıktıDosyası yerine yöntemi writeFileSync

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

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

2

Yinelemeli olarak dizin oluşturmak için özel işlevim (harici bağımlılıklar olmadan):

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

İşte Düğüm 10.12.0'da çalışan fonksiyonum. Umarım bu yardımcı olur.

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!');
        });
    }

0
let name = "./new_folder/" + file_name + ".png";
await driver.takeScreenshot().then(
  function(image, err) {
    require('mkdirp')(require('path').dirname(name), (err) => {
      require('fs').writeFile(name, image, 'base64', function(err) {
        console.log(err);
      });
    });
  }
);

Yalnızca kod yanıtları düşük kaliteli olarak kabul edilir: Kodunuzun ne yaptığını ve sorunu nasıl çözdüğünü açıkladığınızdan emin olun. Gönderinize daha fazla bilgi ekleyebilirseniz, soruyu soran kişiye ve gelecekteki okuyuculara yardımcı olacaktır. Tamamen kod tabanlı yanıtları açıklama
Calos

-1

Myrne Stol'un cevabının ayrı bir cevap olarak ortaya konan bir kısmı:

Bu modül istediğinizi yapar: https://npmjs.org/package/writefile . "Writeefile mkdirp" için Google'da arama yaparken anladım. Bu modül, geri arama almak yerine bir söz verir, bu nedenle önce vaatlerin bazılarını okuduğunuzdan emin olun. Aslında işleri sizin için karmaşık hale getirebilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.