【问题标题】:Node.js File System - Saving unique file namesNode.js 文件系统 - 保存唯一的文件名
【发布时间】:2013-07-30 16:39:50
【问题描述】:

我正在使用节点文件系统来保存上传的图像,使用 while 循环来检查现有文件名,递增++直到有一个唯一的文件名。

代码不工作,在放置我的break; 行时出现SyntaxError: Illegal break statement 错误,以及while 循环在循环中从未正确读取我的fs.exists() 函数。

我在逻辑上在这里做错了什么吗?有没有更简单的方法来确保fs.writeFile() 不会覆盖现有文件?

代码:

  var fileExist = true;
  var fileName = req.files.files[0].name.substr(0, req.files.files[0].name.lastIndexOf('.')) || req.files.files[0].name;
  var fileType = req.files.files[0].name.split('.').pop();
  var fileNumber = 1;

  while (fileExist) {

    fileNumber_str = fileNumber.toString(); 

    var current = fileName + fileNumber_str + '.' + fileType;

    fs.exists( __dirname + "/uploads/" + current, function(exists){

        if (exists) {
            fileNumber++;
        }

        if (!exists) {

            var newPath = __dirname + "/uploads/" + current;
            fs.writeFile(newPath, data, function (err) {
                res.send('saved');
            });

            break;
        }

    });

  }

【问题讨论】:

    标签: javascript node.js while-loop save


    【解决方案1】:

    你试图突破 fs.exists 的回调,这确实是非法的。使用 fs.existsSync 可能更容易

    例如:

    while (fileExist) {
    
        fileNumber_str = fileNumber.toString(); 
    
        var current = fileName + fileNumber_str + '.' + fileType;
    
    
        if (fs.existsSync(__dirname + "/uploads/" + current)) {
            fileNumber++;
        } else {
            var newPath = __dirname + "/uploads/" + current;
            fs.writeFile(newPath, data, function (err) {
                res.send('saved');
            });
    
            break;
        }
    }
    

    【讨论】:

      【解决方案2】:

      回答

      您的代码正在使用 fs.exists 的异步版本。您需要使用同步版本 fs.existsSync 才能使循环正常工作。

      警告

      使用请求提供的名称存储上传的文件是一个坏主意,因为它允许黑客放入相对路径并可能将文件存储在您不希望它们结束的地方。

      同样,允许使用查询字符串中的路径下载这些上传的文件也是一个坏主意。黑客可以这样写:http://example.com/download?fileName=../../somethingnotexposed/

      【讨论】:

      • 我认为这是一个很好的辅助点,但我不知道它是否回答了这个问题......
      • 很好的响应,但是当我为文件名生成一个随机数而不是使用上传的名称时,fs.existsSync() 仍然没有在循环内触发。
      • adotout 的回答类似,但他们发布的代码在循环中正确执行了 fs.existssync。我通过生成随机数来整合您对文件名使用的批评 - 谢谢!
      【解决方案3】:

      在打开文件之前检查文件是否存在是一种反模式 让你容易受到竞争条件的影响:另一个进程可以删除 调用 fs.exists() 和 fs.open() 之间的文件

      你可以使用fsu模块https://github.com/velocityzen/fsu

      【讨论】:

        猜你喜欢
        • 2016-10-03
        • 2020-08-09
        • 2017-07-02
        • 2013-08-22
        • 2017-09-22
        • 2016-08-10
        • 2017-12-14
        • 2011-09-18
        • 2015-11-30
        相关资源
        最近更新 更多