Node.js文件系统-保存唯一的文件名

Node.js File System - Saving unique file names

本文关键字:唯一 文件名 保存 js 文件系统 Node      更新时间:2023-09-26

我使用节点文件系统保存上传的图像,使用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;
        }
    });
  }

您试图突破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;
    }
}

回答

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

警告

使用请求提供的名称存储上传的文件是个坏主意,因为这会让黑客输入相对路径,并可能将文件存储在你不希望它们出现的地方。

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

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

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