使用formadble時 var form = new formidable.IncomingForm(); php
沒設置form.uploadDir(),默認使用的是os.tmpDir(),也就是操做系統當前用戶的默認臨時目錄 測試
執行上傳文件命令時就報錯"EXDEV, rename.....", ui
網上查詢http://ouyo.info/show.php?pid=1898說是權限問題沒法臨時保存文件(沒測試使用 writeFileSync). spa
就手動指定了一個目錄from.uploadDir(__dirname + '/dirname1/dirname2/dirname3....'),指定爲當前應用中的某一個目錄,再測試時就OK了 操作系統
exports.submit = function(dir) { return function(req, res, next) { var form = new formidable.IncomingForm(); form.uploadDir = dir; //fields是表單中全部的參數字段,files是表單中全部的文件對象 form.parse(req, function(err, fields, files) { var img = files.image; var name = fields.name || img.name; var path = join(dir, img.name); fs.rename(img.path, path, function(err) { if (err) return next(err); Photo.create({ name: name, path: img.name }, function(err) { if (err) return next(err); res.redirect('/'); }); }); }); }; };
今天看到了fs部分的內容: code
這裏提到了EXDEV錯誤,緣由是操做不能跨物理磁盤 orm
而在使用formidable時,我是在win7環境下,項目是在E盤,
formidable的默認上傳路徑也就是操做系統當前用戶的臨時目錄是在C盤,
在默認狀況下報EXDEV的錯誤,後來也改爲了E盤下的某路徑,就OK了,
又測試D盤報EXDEV錯,再改成C盤下新建的目錄下又報錯.
由此,能夠肯定錯誤緣由:
formidable上傳是先將文件保存在一個指定的臨時目錄uploadDir中,再將臨時目錄下保存的文件經過fs.rename()移動到指定目錄,而fs.rename()的源路徑與目錄路徑必須對應同一個磁盤,因此設置的臨時目錄也要指定在同一個磁盤下! 對象
若是業務需求必定要跨磁盤移動文件,則能夠使用fs.readStream,fs.writeStream ip
var fs = require('fs'); module.exports = function move (oldPath, newPath, callback) { fs.rename(oldPath, newPath, function (err) { if (err) { if (err.code === 'EXDEV') { copy(); } else { callback(err); } return; } callback(); }); function copy () { var readStream = fs.createReadStream(oldPath); var writeStream = fs.createWriteStream(newPath); readStream.on('error', callback); writeStream.on('error', callback); readStream.on('close', function () { fs.unlink(oldPath, callback); }); readStream.pipe(writeStream); } }