在Node.js中,我们可以使用formidable模块来轻松地实现文件上传功能,代码如下:

var Q = require('q');
var util = require('util');
var fs = require('fs');
var path = require('path');
var moment = require('moment');
var formidable = require('formidable'); var imageUpload = function (){
}; imageUpload.prototype.useFormParseCallback = function(req){
var deferred = Q.defer(); var form = new formidable.IncomingForm();
form.parse(req, deferred.makeNodeResolver());
return deferred.promise;
}; // 确保目录存在
// 如果指定的目录不存在则同步创建(多层次)
imageUpload.prototype.ensureUploadPathExist = function(uploadPath, mode){
if (!fs.existsSync(uploadPath)){
var pathtmp;
uploadPath.split(path.sep).forEach(function(dirname) {
if (pathtmp) {
pathtmp = path.join(pathtmp, dirname);
}
else {
pathtmp = dirname;
}
if (!fs.existsSync(pathtmp)) {
if (!fs.mkdirSync(pathtmp, mode)) {
return false;
}
}
});
} return true;
}; imageUpload.prototype.uploadImage = function(req){
var pathName = '/uploadImgs/';
var uploadPath = path.join(__dirname, '../../public', pathName); this.ensureUploadPathExist(uploadPath); return this.useFormParseCallback(req).then(function(files){
var file = files[1].imagefile;
var fileType = file.type.split('/')[1];
var newFileName = 'upload_' + moment().format('x') + Math.random().toString().substr(2, 10) + '.' + fileType;
fs.renameSync(file.path, uploadPath + newFileName);
return pathName + newFileName;
});
}; module.exports = imageUpload;

  上述代码中使用了模块q来处理Node.js中的回调处理,有关如何使用q可以自己上百度搜索下,这里不再赘述。函数ensureUploadPathExist()可以确保上传文件的目标目录是存在的,如果不存在它会逐级创建。文件被上传在/public/uploadImgs/目录下,并且按照指定的格式进行了重命名以防止文件被覆盖,有问题的地方在fs.renameSync()函数的调用。正常情况下如果上传的目录在本地,执行fs.renameSync()函数重命名文件是不会有问题的,但如果是跨分区重命名,例如在Linux中使用了NFS或者共享目录,则此处会报跨分区重命名的权限错误。解决办法是将fs.renameSync()函数替换为下面的代码:

var readStream = fs.createReadStream(file.path);
var writeStream = fs.createWriteStream(uploadPath + newFileName); var deferred = Q.defer();
util.pump(readStream, writeStream, deferred.makeNodeResolver());
return deferred.promise.then(function() {
fs.unlinkSync(file.path);
return pathName + newFileName;
});

  使用上述代码既可以实现本地文件的上传,也可以实现跨分区的文件上传。

Node.js使用fs.renameSync报cross-device link not permitted错误的更多相关文章

  1. 解决Node.js调用fs.renameSync报错的问题(Error: EXDEV, cross-device link not permitted)

    2014-08-23 今天开始学习Node.js,在写一个文件上传的功能时候,调用fs.renameSync方法错误 出错代码所在如下: function upload(response,reques ...

  2. Node.js用fs.renameSync报cross-device link not permitted错

    转自: http://blog.csdn.net/starrexstar/article/details/8048722 今天把 Manuel Kiessling 的[The Node Beginne ...

  3. node.js的fs核心模块读写文件操作 -----由浅入深

    node.js 里fs模块 常用的功能 实现文件的读写 目录的操作 - 同步和异步共存 ,有异步不用同步 - fs.readFile 都不能读取比运行内存大的文件,如果文件偏大也不会使用readFil ...

  4. nodejs(四)file System模块 解决Cross device link错误 EXDEV

    var fs = require('fs'); /*cross device link fs.rename('c:\\err.LOG','d:\\err.LOG',function(err){ con ...

  5. [node.js] fs.renameSync()报错

    初学node.js,跟着node入门,操作了一遍.在最后一步,上传图片并显示时遇到报错 fs.js: throw err; ^ Error: ENOENT: no such file or direc ...

  6. Node.js:fs文件系统模块

    fs文件系统模块,这是一个非常重要的模块,对文件的操作都基于它.该模块的所有方法都有同步和异步两种方式,下面便介绍一下该模块的使用. 1.检测当前进程对文件的权限 使用fs.access(path[, ...

  7. node.js中fs文件系统模块的使用

    node.js中为我们提供了fs文件系统模块,实现对文件或目录的创建,修改和删除等操作. fs模块中,所有的方法分为同步和异步两种实现. 有 sync 后缀的方法为同步方法,没有 sync 后缀的方法 ...

  8. 关于Node.js的httpClieint请求报错ECONNRESET的原因和解决措施

    背景说明 最近在工作项目中有下面一个场景: 使用Node.js的express框架实现了一个文件系统服务器端,其中有个API用于客户端上传文件.客户端使用Node.js的HttpClient来调用服务 ...

  9. #Node.js的fs导入遇到的问题和解决方案

    一直在使用VS Code,今天打算用Node.js进行文件IO时候遇到了一些问题,fs是Node.js的核心功能之一,一开始我用Javascript编写fs模块的导入. var fs = requir ...

随机推荐

  1. nio加强服务端并发

    究了一下Android推送,方式很多,比如用框架或者用第三方服务,在此并不讨论个中优劣.抱着学习的态度,本人不太喜欢用一些现成的东西,所以自己动手实现了一套简单的推送机制.使用TCP长连接,完成服务器 ...

  2. 【Java】使用iText生成PDF文件

    iText介绍 iText是著名的开放源码的站点sourceforge一个项目,是用于生成PDF文档的一个java类库.通过iText不仅可以生成PDF或rtf的文档,而且可以将XML.Html文件转 ...

  3. NPOI导出Excel(含有超过65335的处理情况)

    NPOI导出Excel的网上有很多,正好自己遇到就学习并总结了一下: 首先说明几点: 1.Excel2003及一下:后缀xls,单个sheet最大行数为65335 Excel2007 单个sheet ...

  4. vagrant 基本配置

    首先安装好virtualbox,可以对照官网教程 https://www.if-not-true-then-false.com/2010/install-virtualbox-with-yum-on- ...

  5. CentOS 7 关闭防火墙

    CentOS 7.0默认使用的是firewall作为防火墙 直接关闭防火墙 systemctl stop firewalld.service #停止firewall systemctl disable ...

  6. 解决拖拽有内容的div的bug和兼容问题

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 31.0px Consolas; color: #2b7ec3 } p.p2 { margin: 0.0px ...

  7. oracle exists

    公司项目中有用到exists,感觉挺有用的,拷贝一些感念的东西. “exists”和“in”的效率问题 1) select * from T1 where exists(select 1 from T ...

  8. [UCSD白板题] Sorting: 3-Way Partition

    Problem Introduction The goal in this problem is to redesign a given implementation of the randomize ...

  9. berkeley db 内存池 LRU算法

    priority based lru in src/mp/mp_fget.c, __memp_fget(), 初始化 一个page buffer时, 设置其 priority: bhp->pri ...

  10. 修改Chrome临时文件位置

    通过目录链接实现. mklink /D "C:\Users\ljq\AppData\Local\Google\Chrome\User Data" z:\temp http://we ...