簡體   English   中英

寫入文件時創建目錄 Node.js

[英]Create Directory When Writing To File In Node.js

一直在鼓搗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 不退出寫入文件,誰能幫我找出如何創建目錄結構?

節點 > 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

您可以使用mkdirpfs-extra 之類的包來解決此問題。 如果您不想安裝軟件包,請參閱下面的 Tiago Peres França 的回答。

如果您不想使用任何額外的包,您可以在創建文件之前調用以下函數:

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

使用node-fs-extra,您可以輕松完成。

安裝它

npm install --save fs-extra

然后使用outputFile方法。 它的文檔說:

幾乎與 writeFile 相同(即覆蓋),除了如果父目錄不存在,則創建它。

您可以通過四種方式使用它:

異步/等待

await fse.outputFile('tmp/test.txt', 'Hey there!');

使用承諾

如果您使用promises ,這是代碼:

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

回調樣式

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.outputFileSync('tmp/test.txt', 'Hey there!')

如需完整參考,請查看outputFile文檔和所有node-fs-extra 支持的方法

無恥的插頭警報!

您必須檢查所需路徑結構中的每個目錄,如果它不存在,則手動創建它。 Node 的 fs 模塊中已經提供了所有這樣做的工具,但您只需使用我的 mkpath 模塊即可完成所有這些操作: https : //github.com/jrajav/mkpath

由於我還不能發表評論,我發布了一個基於@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);
}

我的建議是:當你可以用幾行代碼輕松做到時,盡量不要依賴依賴項

這是您試圖在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);
    });
};

我剛剛發布了這個模塊,因為我需要這個功能。

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

它的工作原理類似於 Node.js fs 方法的包裝器。 所以你可以像使用fs.writeFilefs.writeFileSync一樣使用它(異步和同步寫入)

與上面相同的答案,但async await並准備使用!

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

async function isExists(path) {
  try {
    await fs.access(path);
    return true;
  } catch {
    return false;
  }
};

async function writeFile(filePath, data) {
  try {
    const dirname = path.dirname(filePath);
    const exist = await isExists(dirname);
    if (!exist) {
      await fs.mkdir(dirname, {recursive: true});
    }
    
    await fs.writeFile(filePath, data, 'utf8');
  } catch (err) {
    throw new Error(err);
  }
}

例子:

(async () {
  const data = 'Hello, World!';
  await writeFile('dist/posts/hello-world.html', data);
})();

我一直在修改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創建目錄結構的方法嗎?

這是一個完整的解決方案,用於創建包含所有需要的子文件夾的文件夾,然后寫入文件,所有這些都在一個 function 中完成。

這是一個示例,假設您正在創建一個備份文件並且您想要在 function 中傳遞備份文件夾名稱(因此是變量的名稱)


  createFile(backupFolderName, fileName, fileContent) {
    const csvFileName = `${fileName}.csv`;

    const completeFilePath = join(process.cwd(), 'backups', backupFolderName);

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

    fs.writeFileSync(join(completeFilePath, csvFileName), fileContent, function (err) {
      if (err) throw err;
      console.log(csvFileName + ' file saved');
    })
  }

IDK 為什么,但是如果文件名也包含在路徑中,這個 mkdir 總是用文件名創建一個額外的目錄; 例如

// fileName = './tmp/username/some-random.jpg';
try {
  mkdirSync(fileName, { recursive: true })
} catch (error) {};

在此處輸入圖像描述

解決方案

可以這樣解決: fileName.split('/').slice(0, -1).join('/')只創建目錄到最后一個目錄,而不是文件名本身。

// fileName = './tmp/username/some-random.jpg';
try {
  mkdirSync(fileName.split('/').slice(0, -1).join('/'), { recursive: true })
} catch (error) {};

在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM