2013-07-30 73 views
1

我正在使用節點文件系統保存上傳的圖像,使用while循環檢查現有文件名,遞增++,直到出現唯一文件名。Node.js文件系統 - 保存唯一的文件名

代碼無法正常工作,因爲我的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; 
     } 

    }); 

    } 

回答

2

你試圖擺脫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/

+0

我認爲這是一個很好的輔助點,但我不知道它是否回答這個問題.... –

+0

添加回答:) – AndyD

+0

優秀的響應,但fs.existsSync()仍然沒有在循環內觸發,當我爲文件名生成了一個隨機數,而不是使用上傳的名稱。 – alyx

1

察看文件打開之前存在是一個反模式是 讓你容易受到競爭條件:另一個進程可以刪除 )調用的文件fs.exists()和fs.open(

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