Узел.js создать папку или использовать существующую
Я уже прочитал документацию узла.js и, если я что-то пропустил, он не говорит, какие параметры содержатся в определенных операциях, в частности fs.mkdir(). Как вы можете видеть в документации, это не очень много.
В настоящее время у меня есть этот код, который пытается создать папку или использовать существующую вместо этого:
fs.mkdir(path,function(e){
if(!e || (e && e.code === 'EEXIST')){
//do something with contents
} else {
//debug
console.log(e);
}
});
но интересно, это правильный способ сделать это? Идет проверка на наличие кода EEXIST правильный способ узнать что папка уже существует? Я знаю, что могу сделать fs.stat() перед созданием каталога, но это уже будет два попадания в файловую систему.
во-вторых, есть ли полная или, по крайней мере, более подробная документация узла.js, который содержит сведения о том, какие объекты ошибок содержат, какие параметры означают и т. д.
11 ответов:
хороший способ сделать это-использовать mkdirp модуль.
$ npm install mkdirpиспользуйте его для запуска функции, которая требует каталог. Обратного вызова вызывается после создания пути или если путь уже существует. Ошибка
errустанавливается, если mkdirp не удалось создать путь к каталогу.var mkdirp = require('mkdirp'); mkdirp('/tmp/some/path/foo', function(err) { // path exists unless there was an error });
С помощью
try {} catch {}, вы можете достичь этого очень изящно, не сталкиваясь с условием гонки:отказоустойчивые
fs.mkdirSync(dirPath)const mkdirSync = function (dirPath) { try { fs.mkdirSync(dirPath) } catch (err) { if (err.code !== 'EEXIST') throw err } }Примечание:
dirPathиспользуется в качестве аргумента вместоpath, например, используется в официальной документации узлаfs.mkdirSync, чтобы избежать путаницы с модулем стандартного пути узла.объяснение
узел попытается создать каталог и выдаст исключение, если он встретит исключение делающий так. В
catch {}предложения, мы продолжаем выполнение скрипта, как будто ничего не произошло, если код ошибкиEEXIST, это означает, что каталог существует. Если код ошибки неEEXISTхотя, мы должны бросить ошибку, потому что мы, вероятно, имеем дело с исключением файловой системы, такие какEACCES(отказано в доступе).поскольку между проверкой наличия и созданием каталога нет мертвого времени, мы избегаем условий гонки;
это, однако, может только будьте верны при использовании синхронной версии (такfs.mkdir()не будет работать), но деструктивные операции файловой системы, такие какmkdirдолжны использоваться только синхронно в любом случае.Edit: С тех пор я нашел способ адаптировать ту же концепцию к асинхронному
fs.mkdirчто вы можете найти в этой суть шахтепримеры
давайте создадим каталоги
./first/second/thirdи./first/second/fourth, дано:const fs = require('fs') const path = require('path') const mkdirSync = function (dirPath) { try { fs.mkdirSync(dirPath) } catch (err) { if (err.code !== 'EEXIST') throw err } }Линейный Использования
С помощью функции wrapped выше, вы можете убедиться, что каталоги существуют и создавать их в простой форме.
mkdirSync(path.resolve('./first')) mkdirSync(path.resolve('./first/second')) mkdirSync(path.resolve('./first/second/third')) mkdirSync(path.resolve('./first/second')) // To demonstrate fault tolerance mkdirSync(path.resolve('./first/second/fourth'))Примечание: Вы все еще должны убедиться, что каждая часть пути к каталогу существует. Звоню
mkdirSync(path.resolve('./first/second/third'))непосредственно, не убедившись./firstи./first/secondexist все равно выдаст исключение.рекурсивное использование, как UNIX в
mkdir -pдля того, чтобы обойти недостаток вышесказанное, вы можете обернуть дальше нашу отказоустойчивость
mkdirSync()в рекурсивной функции, которая обеспечит существование каждой части пути:const mkdirpSync = function (dirPath) { const parts = dirPath.split(path.sep) // For every part of our path, call our wrapped mkdirSync() // on the full path until and including that part for (let i = 1; i <= parts.length; i++) { mkdirSync(path.join.apply(null, parts.slice(0, i))) } } // You can now directly create the two target directories mkdirpSync('first/second/third') mkdirpSync('first/second/fourth')
Если вы хотите быстро и грязно один лайнер, используйте это:
fs.existsSync("directory") || fs.mkdirSync("directory");
узел.Яш документы для
fs.mkdirв основном отложите на man-страницу Linux дляmkdir(2). Это означает, чтоEEXISTтакже будет указано, если путь существует, но не является каталогом, который создает неудобный угловой случай, если вы идете по этому маршруту.возможно, вам лучше позвонить
fs.statкоторый скажет вам, Существует ли путь, и если это каталог в одном вызове. Для (что я предполагаю) нормальный случай, когда каталог уже существует, это только один хит файловой системы.эти
fsметоды модуля-это тонкие оболочки вокруг собственных API C, поэтому вам нужно проверить справочные страницы, на которые ссылается узел.JS docs для деталей.
вы можете использовать это:
if(!fs.existsSync("directory")){ fs.mkdirSync("directory", 0766, function(err){ if(err){ console.log(err); // echo the result back response.send("ERROR! Can't make the directory! \n"); } }); }
вам лучше не считать хиты файловой системы, когда вы кодируете в Javascript, на мой взгляд. Однако, (1)
stat&mkdirи (2)mkdirи проверьте (или отбросьте) код ошибки, оба способа-это правильные способы сделать то, что вы хотите.
вы также можете использовать fs-extra, которые обеспечивают много часто используемых файловых операций.
Пример Кода:
var fs = require('fs-extra') fs.mkdirs('/tmp/some/long/path/that/prob/doesnt/exist', function (err) { if (err) return console.error(err) console.log("success!") }) fs.mkdirsSync('/tmp/another/path')документы здесь: https://github.com/jprichardson/node-fs-extra#mkdirsdir-callback
вот код ES6, который я использую для создания каталога (когда он не существует):
const fs = require('fs'); const path = require('path'); function createDirectory(directoryPath) { const directory = path.normalize(directoryPath); return new Promise((resolve, reject) => { fs.stat(directory, (error) => { if (error) { if (error.code === 'ENOENT') { fs.mkdir(directory, (error) => { if (error) { reject(error); } else { resolve(directory); } }); } else { reject(error); } } else { resolve(directory); } }); }); } const directoryPath = `${__dirname}/test`; createDirectory(directoryPath).then((path) => { console.log(`Successfully created directory: '${path}'`); }).catch((error) => { console.log(`Problem creating directory: ${error.message}`) });Примечание:
- в начале
createDirectoryфункция, я нормализую путь, чтобы гарантировать, что тип разделителя пути операционной системы будет использоваться последовательно (например, это превратитсяC:\directory/testнаC:\directory\test(при нахождении на Windows)fs.existsи устаревший, вот почему я используюfs.statчтобы проверить, если каталог уже существует- если каталог не существует, то код ошибки будет
ENOENT(Error НЕТ ЛОРry)- сам каталог будет создан с помощью
fs.mkdir- я предпочитаю асинхронную функцию
fs.mkdirнад ним блокирует коллегаfs.mkdirSyncи из-за упаковкиPromiseбудет гарантировано, что путь к каталогу будет возвращен только после успешного завершения работы Каталога создано
создать динамический каталог имен для каждого пользователя... используйте этот код
***suppose email contain user mail address*** var filessystem = require('fs'); var dir = './public/uploads/'+email; if (!filessystem.existsSync(dir)){ filessystem.mkdirSync(dir); }else { console.log("Directory already exist"); }
Я рекомендую проще :
// Get modules node const fs = require('fs'); const path = require('path'); // Create function mkdirpath(dirPath) { if(!fs.existsSync(dirPath)) { try { fs.mkdirSync(dirPath); } catch(e) { mkdirpath(path.dirname(dirPath)); mkdirpath(dirPath); } } } // Create folder path mkdirpath('my/new/folder/create');
var fs = require('fs'); if (fs.existsSync('temp')) { console.log('Directory exists, removing...'); if (fs.existsSync('temp/new.txt')) { fs.unlinkSync('temp/new.txt'); } fs.rmdirSync('temp'); } fs.mkdirSync('temp'); if (fs.existsSync('temp')) { process.chdir('temp'); fs.writeFileSync('test.txt', 'This is some test text for the file'); fs.renameSync('test.txt','new.txt'); console.log('File has size: ' + fs.statSync('new.txt').size + ' bytes'); console.log('File contents: ' + fs.readFileSync('new.txt').toString()); }
Comments