Странное поведение с fs.rename: удаление файла (node.js)

Я хотел написать собственный скрипт, который бы рекурсивно переименовал все файлы в каталог, содержащий точку в имени файла. Как: mv 'foo.bar.avi' 'foo bar.avi'

Он также преобразует имена каталогов, например, "abc/xyzmp4", становится "a b c/x y.mp4" и удаляет все подчеркивания _.

Результатом стало удаление всех файлов в этом каталоге, в результате чего остались только некоторые пустые каталоги без каких-либо уведомлений или ошибок, что определенно привело к потере около 300 Гбайт данных без резервных копий.

Есть замечательный код, который позволил этот подвиг:

var fs = require('fs');
var path = require('path');
var util = require('util');
var fse = require('fs-extra')
var async = require('async');
var walk = function(dir, done) {
  var results = [];
  fs.readdir(dir, function(err, list) {
    if (err) return done(err);
    var pending = list.length;
    if (!pending) return done(null, results);
    list.forEach(function(file) {
      file = path.resolve(dir, file);
      fs.stat(file, function(err, stat) {
        if (stat && stat.isDirectory()) {
          walk(file, function(err, res) {
            results = results.concat(res);
            if (!--pending) done(null, results);
          });
        } else {
          if (file.indexOf('/.') < 0) {
            results.push(file);
          }
          if (!--pending) done(null, results);
        }
      });
    });
  });
};
var rename = function(err, filename) {
    if (util.isArray(filename)) {
      for (var i = 0; i < filename.length; i++) {
        rename(err, filename[i]);
      }
      return;
    }
    fs.stat(filename, function(err, stat) {
      if (!stat.isDirectory()) {
        filename2 = filename.split('.');
        var extension = filename2.pop();
        filename2 = filename2.join(' ').split('_').join(' ') + '.' + extension;
        var directory = filename2.split('/');
        directory.pop();
        directory = directory.join('/');
        async.series([
          function (callback) {
            fse.mkdirs(directory, function (err) {
              callback(err, 'fs.mkdirs');
            });
          },
          function(callback) {
            fs.rename(filename, filename2, function (err) {
              callback(err, 'fs.rename');
            });
          }
        ],
        function (err, results) {
          if (err) {
            console.log(err);
          }
          console.log('All files have been renamed');
        });
      }
    });
}
walk('/Volumes/My Passport/Movies/', function(err, results) {
    rename('', results);
});

Уже слишком поздно что-либо делать, я уже оплакиваю эту потерю.

Я просто хотел бы понять, как это fs.rename может удалить файлы.

Я не могу поверить, что я сделал это. Я даже не злюсь, это удивительно. Мой скрипт удалил 300 ГБ данных без единой инструкции об удалении. Я принял мою веру.

Я подозреваю, что fs.rename глючит на внешних дисках.

Спасибо.

1 ответ

Жаль, но проблема в том, что вы забыли var при объявлении filename2, Таким образом, filename2 стал глобальной переменной. fs.rename получал одно и то же значение каждый раз. Решением будет либо объявить filename2 как var filename2 или избавиться от async.series,

Другие вопросы по тегам