Node.js создать папку или использовать существующие

Я уже прочитал документацию Node.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() перед созданием каталога, но это уже два удара файловой системы.

Во-вторых, существует ли полная или, по крайней мере, более подробная документация Node.js, которая содержит сведения о том, какие объекты ошибок содержат, какие значения параметров и т.д.

Ответ 1

Хороший способ сделать это - использовать mkdirp модуль.

$ npm install mkdirp

Используйте его для запуска функции, требующей каталога. Обратный вызов вызывается после создания пути или если путь уже существует. Ошибка err устанавливается, если mkdirp не удалось создать путь к каталогу.

var mkdirp = require('mkdirp');
mkdirp('/tmp/some/path/foo', function(err) { 

    // path exists unless there was an error

});

Ответ 2

Изменить: Поскольку этот ответ очень популярен, я обновил его, чтобы отразить современные практики.

Используя try {} catch (err) {}, вы можете достичь этого очень изящно, не сталкиваясь с условиями гонки.

Чтобы предотвратить потерю времени между проверкой существования и созданием каталога, мы просто пытаемся создать его прямо вверх и игнорировать ошибку, если это EEXIST (каталог уже существует).

Однако, если ошибка не EEXIST, мы должны выбросить ошибку, потому что мы можем иметь дело с чем-то вроде EPERM или EACCES

Мы также можем использовать опцию recursive в mkdir, чтобы иметь поведение, подобное mkdir -p (Примечание: доступно только в Node> = 10.x)

Синхронизировать версию

const fs = require('fs')

function ensureDirSync (dirpath) {
  try {
    fs.mkdirSync(dirpath, { recursive: true })
  } catch (err) {
    if (err.code !== 'EEXIST') throw err
  }
}

try {
  ensureDirSync('a/b/c')
  console.log('Directory created')
} catch (err) {
  console.error(err)
}

Асинхронная версия (асинхронная/ожидающая, современные версии Node)

const fs = require('fs').promises

async function ensureDir (dirpath) {
  try {
    await fs.mkdir(dirpath, { recursive: true })
  } catch (err) {
    if (err.code !== 'EEXIST') throw err
  }
}

async function main () {
  try {
    await ensureDir('a/b/c')
    console.log('Directory created')
  } catch (err) {
    console.error(err)
  }
}

main()

Если вы предпочитаете не использовать экспериментальный API fs.promises (хотя он стабилен и готов остаться), вы можете самостоятельно обернуть fs.mkdir:

await new Promise((resolve, reject) => {
  fs.mkdir(dirpath, { recursive: true }, err => err ? reject(err) : resolve())
})

Асинхронная версия (обещания, устаревшие версии Node)

Примечание. Поскольку у нас нет новой опции recursive в версиях узлов до 10.x, мы должны убедиться, что каждая часть пути создана.

const fs = require('fs')

function ensureDir (dirpath) {
  return fs.mkdir(dirpath, function (err) {
    if (err.code === 'EEXIST') {
      return Promise.resolve()
    } else {
      return Promise.reject(err)
    }
  })
}

Promise.resolve()
  .then(function () { ensureDir('a') })
  .then(function () { ensureDir('a/b') })
  .then(function () { ensureDir('a/b/c') })
  .then(function () { console.log('Directory created') })
  .catch(function () { console.error(err) })

Ответ 3

Если вам нужен быстрый и грязный один лайнер, используйте это:

fs.existsSync("directory") || fs.mkdirSync("directory");

Ответ 4

Документы node.js для fs.mkdir в основном откладывают на страницу руководства Linux для mkdir(2). Это указывает на то, что EEXIST также указывается, если путь существует, но не является каталогом, который создает неудобный угловой регистр, если вы идете по этому маршруту.

Возможно, вам лучше позвонить fs.stat, который скажет вам, существует ли путь и если он является каталогом в одном вызове. Для (что я предполагаю) нормальный случай, когда каталог уже существует, он ударил только одну файловую систему.

Эти методы модуля fs - это тонкие обертки вокруг собственных API-интерфейсов C, поэтому вам нужно проверить справочные страницы, указанные в документах node.js, для деталей.

Ответ 5

Вы можете использовать это:

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

Ответ 6

Я предлагаю решение без модулей (накапливать модули никогда не рекомендуется для удобства обслуживания, особенно для небольших функций, которые можно записать в несколько строк...):

ПОСЛЕДНИЕ ОБНОВЛЕНИЯ:

В v10.12.0 NodeJS реализует рекурсивные параметры:

// Create recursive folder
fs.mkdir('my/new/folder/create', { recursive: true }, (err) => { if (err) throw err; });

ОБНОВЛЕНИЕ:

// Get modules node
const fs   = require('fs');
const path = require('path');

// Create 
function mkdirpath(dirPath)
{
    if(!fs.accessSync(dirPath, fs.constants.R_OK | fs.constants.W_OK))
    {
        try
        {
            fs.mkdirSync(dirPath);
        }
        catch(e)
        {
            mkdirpath(path.dirname(dirPath));
            mkdirpath(dirPath);
        }
    }
}

// Create folder path
mkdirpath('my/new/folder/create');

Ответ 7

Вот код 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 ( E rror НЕТ ENT ry)
  • Сама директория будет создана с помощью fs.mkdir
  • Я предпочитаю асинхронную функцию fs.mkdir над ней, блокирующую экземпляр fs.mkdirSync, и из-за обертывания Promise будет гарантировано, что путь к каталогу будет возвращен только после успешного создания каталога.

Ответ 8

Лучше не считать хиты файловой системы, пока, на мой взгляд, код Javascript. Однако, (1) stat и mkdir и (2) mkdir и проверьте (или отмените) код ошибки, оба способа - правильные способы делать то, что вы хотите.

Ответ 9

Вы также можете использовать 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')

docs здесь: https://github.com/jprichardson/node-fs-extra#mkdirsdir-callback

Ответ 10

создать динамический каталог имен для каждого пользователя... используйте этот код

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

Ответ 11

Raugaral ответ, но с функциональностью -p. Некрасиво, но работает

function mkdirp(dir) {
    let dirs = dir.split(/\\/).filter(asdf => !asdf.match(/^\s*$/))
    let fullpath = ''

    // Production directory will begin \\, test is on my local drive.
    if (dirs[0].match(/C:/i)) {
        fullpath = dirs[0] + '\\'
    }
    else {
        fullpath = '\\\\' + dirs[0] + '\\'
    }

    // Start from root directory + 1, build out one level at a time.
    dirs.slice(1).map(asdf => {
        fullpath += asdf + '\\'
        if (!fs.existsSync(fullpath)) {
            fs.mkdirSync(fullpath)
        }
    })
}//mkdirp

Ответ 12

Точно так же, как новая альтернатива ответа Теему Иконен, которая очень проста и легко читаема, заключается в использовании метода ensureDir пакета fs-extra.

Его можно использовать не только как явную замену встроенному модулю fs, но также имеет множество других функций в дополнение к функциональности пакета fs.

Метод ensureDir, как следует из названия, гарантирует, что каталог существует. Если структура каталогов не существует, она создается. Как mkdir -p. Не только конечная папка, но и весь путь, если он еще не создан.

приведенная выше версия async. Он также имеет синхронный метод для выполнения этого в форме метода ensureDirSync.

Ответ 13

Вы можете сделать все это с помощью модуля Файловая система.

const
  fs = require('fs'),
  dirPath = 'path/to/dir'

// Check if directory exists.
fs.access(dirPath, fs.constants.F_OK, (err)=>{
  if (err){
    // Create directory if directory does not exist.
    fs.mkdir(dirPath, {recursive:true}, (err)=>{
      if (err) console.log('Error creating directory: ${err}')
      else console.log('Directory created successfully.')
    })
  }
  // Directory now exists.
})

Вам действительно даже не нужно проверять, существует ли каталог. Следующий код также гарантирует, что каталог уже существует или создан.

const
  fs = require('fs'),
  dirPath = 'path/to/dir'

// Create directory if directory does not exist.
fs.mkdir(dirPath, {recursive:true}, (err)=>{
  if (err) console.log('Error creating directory: ${err}')
  // Directory now exists.
})

Ответ 14

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