Рекурсивное создание каталогов для Node.js 0.5.x

У меня есть функция, которая загружает файл и сохраняет его во вложенной структуре каталогов на основе отправленных в него параметров (например: ./somedir/a/b/c или ./ somedir2 / a / d / b). Я не могу поверить, что какой-либо каталог на этом пути был создан, поэтому мне нужно, чтобы каждый каталог по пути к файлу был проверен и создан, если он не существует. Теперь у меня есть код, который отлично работает для Node 0.4.x, но что-то сломалось, по крайней мере, в версии Node 0.5.x для Windows (проверенной специально на 0.5.10).

Я ужасно разбираюсь в файловых системах, поэтому, если бы кто-нибудь мог понять, как я могу заставить эту работу работать или заменить ее чем-то другим, работающим аналогичным образом, я был бы очень признателен. Цель состоит в том, чтобы иметь код, который будет правильно работать как в Unix, так и в Windows, а также в Node 0.4.x и 0.5.x.

// automatically create directories if they do not exist at a path
function mkdirs(_path, mode, callback) {
  var dirs = _path.split("/");
  var walker = [dirs.shift()];

  var walk = function (ds, acc, m, cb) {
    if (ds.length > 0) {
      var d = ds.shift();
      acc.push(d);
      var dir = acc.join("/");

      fs.stat(dir, function (err, stat) {
        if (err) {
          // file does not exist
          if (err.errno == 2) {
            fs.mkdir(dir, m, function (erro) {
              if (erro && erro.errno != 17) {
                terminal.error(erro, "Failed to make " + dir);
                return cb(new Error("Failed to make " + dir + "\n" + erro));
              } else {
                return walk(ds, acc, m, cb);
              }
            });
          } else {
            return cb(err);
          }
        } else {
          if (stat.isDirectory()) {
            return walk(ds, acc, m, cb);
          } else {
            return cb(new Error("Failed to mkdir " + dir + ": File exists\n"));
          }
        }
      });
    } else {
      return cb();
    }
  };
  return walk(dirs, walker, mode, callback);
};

Пример использования:

mkdirs('/path/to/file/directory/', 0777, function(err){

РЕДАКТИРОВАТЬ: Обновление для Node 0.8.x (в CoffeeScript):

# 
# Function mkdirs
# Ensures all directories in a path exist by creating those that don't
# @params
#    path:      string of the path to create (directories only, no files!)
#    mode:      the integer permission level
#    callback:  the callback to be used when complete
# @callback
#    an error object or false
#
mkdirs = (path, mode, callback) ->
  tryDirectory = (dir, cb) ->
    fs.stat dir, (err, stat) ->
      if err #the file doesn't exist, try one stage earlier then create
        if err.errno is 2 or err.errno is 32 or err.errno is 34
          if dir.lastIndexOf("/") is dir.indexOf("/") #only slash remaining is initial slash
            #should only be triggered when path is '/' in Unix, or 'C:/' in Windows
            cb new Error("notfound")
          else
            tryDirectory dir.substr(0, dir.lastIndexOf("/")), (err) ->
              if err #error, return
                cb err
              else #make this directory
                fs.mkdir dir, mode, (error) ->
                  if error and error.errno isnt 17
                    cb new Error("failed")
                  else
                    cb()
        else #unkown error
          cb err
      else
        if stat.isDirectory() #directory exists, no need to check previous directories
          cb()
        else #file exists at location, cannot make folder
          cb new Error("exists")
  path = (if path.indexOf("\\") >= 0 then path.replace("\\", "/") else path) #change windows slashes to unix
  path = path.substr(0, path.length - 1)  if path.substr(path.length - 1) is "/" #remove trailing slash
  tryDirectory path, callback
9
задан geoffreak 29 October 2012 в 20:34
поделиться