นี่เป็นวิธีที่ถูกต้องในการสร้างไดเรกทอรีหรือไม่หากไม่มีอยู่ ควรได้รับอนุญาตอย่างเต็มที่สำหรับสคริปต์และผู้อื่นสามารถอ่านได้
var dir = __dirname + '/upload';
if (!path.existsSync(dir)) {
fs.mkdirSync(dir, 0744);
}
นี่เป็นวิธีที่ถูกต้องในการสร้างไดเรกทอรีหรือไม่หากไม่มีอยู่ ควรได้รับอนุญาตอย่างเต็มที่สำหรับสคริปต์และผู้อื่นสามารถอ่านได้
var dir = __dirname + '/upload';
if (!path.existsSync(dir)) {
fs.mkdirSync(dir, 0744);
}
คำตอบ:
var fs = require('fs');
var dir = './tmp';
if (!fs.existsSync(dir)){
fs.mkdirSync(dir);
}
Sync
เมธอด* มักจะไม่มีข้อห้าม: ไม่ต้องการบล็อกลูปของเหตุการณ์
ไม่ได้ด้วยเหตุผลหลายประการ
path
โมดูลไม่ได้มีexists
/ existsSync
วิธีการ มันอยู่ในfs
โมดูล (บางทีคุณอาจพิมพ์ผิดในคำถามของคุณ?)
เอกสารอย่างชัดเจนกีดกันexists
คุณจากการใช้
fs.exists()
เป็นสมัยและมีเหตุผลทางประวัติศาสตร์เท่านั้น ไม่ควรมีเหตุผลที่จะใช้มันในรหัสของคุณเองโดยเฉพาะอย่างยิ่งการตรวจสอบว่าไฟล์ที่มีอยู่ก่อนที่จะเปิดมันคือการต่อต้านรูปแบบที่ใบคุณเสี่ยงกับสภาพการแข่งขัน: กระบวนการอื่นอาจลบไฟล์ระหว่างสายไปและ
fs.exists()
fs.open()
เพียงเปิดไฟล์และจัดการข้อผิดพลาดเมื่อไม่มี
เนื่องจากเรากำลังพูดถึงไดเรกทอรีมากกว่าไฟล์คำแนะนำนี้หมายถึงคุณควรเพียงแค่ไม่มีเงื่อนไขโทรและไม่สนใจmkdir
EEXIST
โดยทั่วไปคุณควรหลีกเลี่ยงSync
วิธี* พวกเขากำลังบล็อกซึ่งหมายความว่าไม่มีอะไรอย่างอื่นในโปรแกรมของคุณที่สามารถเกิดขึ้นได้ในขณะที่คุณไปที่ดิสก์ นี่คือการดำเนินการที่มีราคาแพงมากและเวลาที่ใช้ในการแบ่งสมมติฐานหลักของการวนรอบเหตุการณ์ของโหนด
Sync
วิธีการ* มักใช้กับสคริปต์ด่วนแบบใช้ครั้งเดียว (ซึ่งทำสิ่งใดสิ่งหนึ่งและจากนั้นออก) แต่แทบจะไม่ควรใช้เมื่อคุณเขียนเซิร์ฟเวอร์: เซิร์ฟเวอร์ของคุณจะไม่สามารถตอบสนองกับใครได้ตลอดระยะเวลาที่ผ่านมา ของคำขอ I / O หากคำขอของไคลเอนต์หลายรายการต้องการการดำเนินการ I / O เซิร์ฟเวอร์ของคุณจะหยุดทำงานอย่างรวดเร็ว
ครั้งเดียวที่ฉันจะพิจารณาใช้Sync
เมธอด* ในแอปพลิเคชันเซิร์ฟเวอร์คือการทำงานที่เกิดขึ้นครั้งเดียว (และเพียงครั้งเดียว) เมื่อเริ่มต้น ตัวอย่างเช่นrequire
ใช้readFileSync
เพื่อโหลดโมดูลจริง ๆ
ถึงอย่างนั้นคุณก็ยังต้องระวังเพราะ I / O แบบซิงโครนัสจำนวนมากสามารถชะลอเวลาเริ่มต้นเซิร์ฟเวอร์ของคุณโดยไม่จำเป็น
คุณควรใช้เมธอด I / O แบบอะซิงโครนัสแทน
ดังนั้นหากเรารวมคำแนะนำเหล่านั้นเข้าด้วยกันเราจะได้อะไรเช่นนี้:
function ensureExists(path, mask, cb) {
if (typeof mask == 'function') { // allow the `mask` parameter to be optional
cb = mask;
mask = 0777;
}
fs.mkdir(path, mask, function(err) {
if (err) {
if (err.code == 'EEXIST') cb(null); // ignore the error if the folder already exists
else cb(err); // something else went wrong
} else cb(null); // successfully created folder
});
}
และเราสามารถใช้สิ่งนี้:
ensureExists(__dirname + '/upload', 0744, function(err) {
if (err) // handle folder creation error
else // we're all good
});
แน่นอนว่านี่ไม่ได้หมายถึงกรณีขอบเช่น
0744 == 484
.
ฉันได้พบและโมดูล npm ที่ทำงานเหมือนมีเสน่ห์สำหรับเรื่องนี้ มันจะทำ mkdir แบบวนซ้ำเมื่อต้องการเช่น "mkdir -p"
mkdir
วิธีการมีความสามารถในการซ้ำสร้างไดเรกทอรีใด ๆ ในเส้นทางที่ไม่อยู่และไม่สนใจคนที่ทำ
จากNode v10 / 11 docs :
// 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
โมดูลในตัวก่อน
ต่อไปนี้เป็นตัวอย่างที่มีประสิทธิภาพมากกว่านี้เล็กน้อยที่ใช้ประโยชน์จากโมดูล ES ดั้งเดิม (ที่เปิดใช้งานการตั้งค่าสถานะและส่วนขยาย. mjs) จัดการเส้นทางที่ไม่ใช่รูทและบัญชีสำหรับชื่อเส้นทางแบบเต็ม:
import fs from 'fs';
import path from 'path';
createDirectories(pathname) {
const __dirname = path.resolve();
pathname = pathname.replace(/^\.*\/|\/?[^\/]+\.[a-z]+|\/$/g, ''); // Remove leading directory markers, and remove ending /file-name.extension
fs.mkdir(path.resolve(__dirname, pathname), { recursive: true }, e => {
if (e) {
console.error(e);
} else {
console.log('Success');
}
});
}
createDirectories('/components/widget/widget.js');
คุณสามารถใช้มันเหมือน
และแน่นอนคุณอาจต้องการที่จะได้รับจินตนาการมากขึ้นโดยใช้สัญญากับ async / รอเพื่อยกระดับการสร้างไฟล์ในแบบซิงโครนัสที่อ่านได้ง่ายขึ้นเมื่อสร้างไดเรกทอรี แต่นั่นอยู่นอกเหนือขอบเขตของคำถาม
ในกรณีที่ผู้ใดสนใจรุ่นบรรทัดเดียว :)
//or in typescript: import * as fs from 'fs';
const fs = require('fs');
!fs.existsSync(dir) && fs.mkdirSync(dir);
คุณสามารถใช้mkdir
และตรวจจับข้อผิดพลาดหากมีโฟลเดอร์อยู่
นี่คือ async (วิธีปฏิบัติที่ดีที่สุด) และปลอดภัย
fs.mkdir('/path', err => {
if (err && err.code != 'EEXIST') throw 'up'
.. safely do your stuff here
})
(เลือกเพิ่มอาร์กิวเมนต์ที่สองด้วยโหมด)
ความคิดอื่น ๆ:
คุณสามารถใช้ในขณะนั้นหรือรอโดยใช้การแนะนำแบบเนทีฟ
const util = require('util'), fs = require('fs');
const mkdir = util.promisify(fs.mkdir);
var myFunc = () => { ..do something.. }
mkdir('/path')
.then(myFunc)
.catch(err => { if (err.code != 'EEXIST') throw err; myFunc() })
คุณสามารถสร้างวิธีการสัญญาของคุณเองเช่น (ยังไม่ทดลอง):
let mkdirAsync = (path, mode) => new Promise(
(resolve, reject) => mkdir (path, mode,
err => (err && err.code !== 'EEXIST') ? reject(err) : resolve()
)
)
สำหรับการตรวจสอบแบบซิงโครนัสคุณสามารถใช้:
fs.existsSync(path) || fs.mkdirSync(path)
หรือคุณสามารถใช้ห้องสมุดทั้งสองกำลังเป็นที่นิยมมากที่สุด
mkdir('/path').catch(err => { if (err.code != 'EEXIST') throw err;}).then(myFunc);
!==
แทน!=
ด้วยแพ็กเกจfs-extraคุณสามารถทำได้โดยใช้สายการบินเดียว :
const fs = require('fs-extra');
const dir = '/tmp/this/path/does/not/exist';
fs.ensureDirSync(dir);
var dir = 'path/to/dir';
try {
fs.mkdirSync(dir);
} catch(e) {
if (e.code != 'EEXIST') throw e;
}
Apr 2018
: nodejs.org/api/fs.html#fs_fs_existssync_path
var filessystem = require('fs');
var dir = './path/subpath/';
if (!filessystem.existsSync(dir)){
filessystem.mkdirSync(dir);
}else
{
console.log("Directory already exist");
}
สิ่งนี้อาจช่วยคุณได้ :)
ENOENT: ไม่มีไฟล์หรือไดเรกทอรีดังกล่าว
สารละลาย
const fs = require('fs') // in javascript
import * as fs from "fs" // in typescript
import fs from "fs" // in typescript
// it will create the directory if it does not exist.
!fs.existsSync(`./assets/`) && fs.mkdirSync(`./assets/`, { recursive: true })
ฉันต้องการที่จะเพิ่ม refactor typescript สัญญาของคำตอบของ josh3736
มันทำสิ่งเดียวกันและมีกรณีขอบเหมือนกันมันเพิ่งเกิดขึ้นกับการใช้สัญญาพิมพ์ดีด typescript และทำงานกับ "ใช้เข้มงวด"
// https://en.wikipedia.org/wiki/File_system_permissions#Numeric_notation
const allRWEPermissions = parseInt("0777", 8);
function ensureFilePathExists(path: string, mask: number = allRWEPermissions): Promise<void> {
return new Promise<void>(
function(resolve: (value?: void | PromiseLike<void>) => void,
reject: (reason?: any) => void): void{
mkdir(path, mask, function(err: NodeJS.ErrnoException): void {
if (err) {
if (err.code === "EEXIST") {
resolve(null); // ignore the error if the folder already exists
} else {
reject(err); // something else went wrong
}
} else {
resolve(null); // successfully created folder
}
});
});
}
ด้วยโหนด 10 + ES6:
import path from 'path';
import fs from 'fs';
(async () => {
const dir = path.join(__dirname, 'upload');
try {
await fs.promises.mkdir(dir);
} catch (error) {
if (error.code === 'EEXIST') {
// Something already exists, but is it a file or directory?
const lstat = await fs.promises.lstat(dir);
if (!lstat.isDirectory()) {
throw error;
}
} else {
throw error;
}
}
})();
คุณสามารถใช้คำสั่งโหนดFile System fs.statเพื่อตรวจสอบว่ามี dir อยู่หรือไม่และfs.mkdirเพื่อสร้างไดเรกทอรีด้วยการติดต่อกลับหรือfs.mkdirSyncเพื่อสร้างไดเรกทอรีโดยไม่มีการเรียกกลับเช่นนี้:
//first require fs
const fs = require('fs');
// Create directory if not exist (function)
const createDir = (path) => {
// check if dir exist
fs.stat(path, (err, stats) => {
if (stats.isDirectory()) {
// do nothing
} else {
// if the given path is not a directory, create a directory
fs.mkdirSync(path);
}
});
};
นี่เป็นฟังก์ชั่นเล็กน้อยในการสร้างไดเรกทอรีซ้ำ ๆ :
const createDir = (dir) => {
// This will create a dir given a path such as './folder/subfolder'
const splitPath = dir.split('/');
splitPath.reduce((path, subPath) => {
let currentPath;
if(subPath != '.'){
currentPath = path + '/' + subPath;
if (!fs.existsSync(currentPath)){
fs.mkdirSync(currentPath);
}
}
else{
currentPath = subPath;
}
return currentPath
}, '')
}
ใช้ async / คอย:
const mkdirP = async (directory) => {
try {
return await fs.mkdirAsync(directory);
} catch (error) {
if (error.code != 'EEXIST') {
throw e;
}
}
};
คุณจะต้องสัญญาfs
:
import nodeFs from 'fs';
import bluebird from 'bluebird';
const fs = bluebird.promisifyAll(nodeFs);