【问题标题】:Renaming files fails when 2 are added simultaneously同时添加 2 个文件时重命名文件失败
【发布时间】:2014-07-27 18:38:10
【问题描述】:

以下脚本在监视文件夹中是否有新的 .ogg 文件时运行良好。它成功地用新文件名创建了一个文件夹,然后根据文件的创建日期重命名文件/

但是,当我在脚本尝试创建一个已经存在的文件夹的同时添加多个文件时,就会出现问题,这表明它以某种方式混淆了两个文件名。有人对我可能做错了什么有任何建议吗?我认为它的代码结构很简单,尽管我无法弄清楚原因。

var baseDir = './',
    path = require('path'),
    fs = require('fs');

// watch the directory for new files
fs.watch(baseDir,  function(event, file) {

    var ext = path.extname(file)
        basename = path.basename(file).substring(0, path.basename(file).length - ext.length);

    // check it wasnt a delete action
    fs.exists(baseDir + file, function(exists) {

        // check we have the right file type
        if(exists && ext === '.ogg'){

            // get the created date
            fs.stat(baseDir + file, function (err, stats){

                if (err)
                    throw err;

                var year = stats.ctime.getFullYear();
                var month = stats.ctime.getMonth()+1;
                var day = stats.ctime.getDate();
                var hour = stats.ctime.getHours();
                var sec = stats.ctime.getSeconds();

                if(month < 10){
                    month = '0' + month;
                }
                if(day < 10){
                    day = '0' + day;
                }
                if(hour < 10){
                    hour = '0' + hour;
                }
                if(sec < 10){
                    sec = '0' + sec;
                }

                var name = year + '' + month + '' + day + '' + hour + '' + sec;

                // does the basename directory exist?
                fs.exists(baseDir + '/' + basename, function(exists) {

                    // if the directory doesnt exist
                    if(!exists){

                        // make the directory
                        fs.mkdir(baseDir + '/' + basename, 0777, function (err, stats){

                            if (err)
                                throw err;

                            moveFile(file, basename, name, ext);

                        });

                    } else {

                        moveFile(file, basename, name, ext);

                    }

                });

            });

        }

    });

});

function moveFile(file, basename, name, ext){

    // move the file to the new directory
    fs.rename(baseDir + file, baseDir + '/' + basename + '/' + name + ext, function (err) {

        if (err)
            throw err;

        // console.log('Rename complete');

    });

}

【问题讨论】:

  • 您是否希望两个文件都在同一个目录中(而您的代码没有这样做)?或者您希望每个文件有一个目录(因此当两个时间戳冲突时会出现问题)?
  • 你应该使用同步调用。当fs.exists 的回调触发时,该文件可能不再存在。您可以使用fs.existsSync 避免此问题。 (所有fs 呼叫也是如此)
  • 差点忘了,但fs.mkdir 会被fs.watch 接走。这可能会产生额外的问题,您应该根据 event 参数进行过滤。

标签: javascript node.js path fs


【解决方案1】:

好的,所以我有几分钟的额外时间,决定去找你。我稍微重构了你的代码,但基本结构应该很容易识别。

var baseDir = './test', 路径 = 要求('路径'), fs = 要求('fs'); // 监视目录中的新文件 fs.watch(baseDir,函数(事件,文件){ var ext = path.extname(文件), basename = path.basename(file).substring(0, path.basename(file).length - ext.length); // 检查它不是删除操作 // 检查我们有正确的文件类型 var filePath = path.join(baseDir, file); if(fs.existsSync(filePath) && ext === '.ogg'){ // 获取创建日期 var stats = fs.statSync(filePath); var name = getName(stats); // 如果目录不存在 var baseDirPath = path.join(baseDir, basename); if(!fs.existsSync(baseDirPath)){ // 建立目录 fs.mkdirSync(baseDirPath, 0777); } moveFile(file, basename, name, ext); } }); 函数getName(统计){ var year = stats.ctime.getFullYear(); var 月 = stats.ctime.getMonth()+1; var day = stats.ctime.getDate(); var hour = stats.ctime.getHours(); // 需要几分钟! var 分钟 = stats.ctime.getMinutes(); var sec = stats.ctime.getSeconds(); 如果(月 %lt 10){ 月 = '0' + 月; } 如果(第 10 天){ 天 = '0' + 天; } 如果(小时 &lt 10){ 小时 = '0' + 小时; } 如果(分钟

一些提示/更正:

  1. 在处理此类简单脚本时,坚持使用以 Sync 结尾的同步 fs 方法。虽然 node.js 以其异步能力而闻名,但它有点过早的优化 IMO。例如,如果您需要将其嵌入到高性能网络服务器中,请在此时优化,而不是之前。

  2. 您在创建新文件名时缺少minutes 变量。这很有可能导致名称冲突,所以我更正了它。

  3. 尝试使用path 库(如path.join)对您更有优势,因为手动加入路径字符串通常会导致代码脆弱。

  4. 仍有几个边缘情况可能导致崩溃。创建一个不带扩展名的文件,该文件与您将基于另一个文件创建的目录同名。 (文件不能成为目录,也不能在另一个文件中移动文件。)。如果您打算进入生产环境,您将希望通过至少一些单元测试来强化代码。

干杯,

【讨论】:

  • 您说“异步是过早的优化”。不仅如此,它是错误的原因。
  • 过早的优化是一个错误。
猜你喜欢
  • 2016-12-08
  • 1970-01-01
  • 2020-08-08
  • 2017-06-23
  • 1970-01-01
  • 2013-03-06
  • 2020-08-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多