起因
近期在研究**nodejs**技术,发现了一个很有意思的方法**fs.rename**,
在网上冲浪时搜索到的用法是**fs.rename(oldPath,newPath,callbacj)**,搜索到的案例中用法如下:
var form = formidable.IncomingForm();
//保持原有扩展名
form.keepExtensions = true;
//设置上传目录
form.uploadDir = __dirname + "/files/";
form.parse(req,function(err,fields,files){
if(err) throw err;
console.log(fields);
let oldFilename = files.up_file.name;
//重命名上传的文件
fs.rename(files.up_file.path, form.uploadDir + generateFilename(oldFilename),err=>{
if(err) {
console.log("重命名失败");
console.log(err);
}else{
console.log("重命名成功!");
}
})
res.writeHead(200,{"Content-type":"text/html;charset='utf-8'"});
res.write('<meta charset="UTF-8" />');
res.end("<h1>上传结束</h1>");
})
function generateFilename(oldFilename){
//将老的文件名拼上时间戳,这样既不会命名冲突又可以看出文件的上传事件
let d = new Date();
let names = oldFilename.split(".");
return `${names[0]}_${""+d.getFullYear() + (d.getMonth()+1) + d.getDate() +'_'+ d.getHours() + d.getMinutes() + d.getSeconds()}.${names[1]}`;
}
如上代码所示,fs.rename的用法为 fs.rename(files.up_file.path, form.uploadDir + generateFilename(oldFilename),callback),在运行项目时未发现files.up_file.path的值
其中files打印数据如下:
{
file: PersistentFile {
_events: [Object: null prototype] { error: [Function (anonymous)] },
_eventsCount: 1,
_maxListeners: undefined,
lastModifiedDate: 2022-11-01T07:02:56.420Z,
filepath: 'C:\\Users\\Desktop\\test\\upload\\9d2c67cb780b50409a3b25400',
newFilename: '9d2c67cb780b50409a3b25400',
originalFilename: '测试.txt',
mimetype: 'text/plain',
hashAlgorithm: false,
size: 14,
_writeStream: WriteStream {
_writableState: [WritableState],
_events: [Object: null prototype],
_eventsCount: 1,
_maxListeners: undefined,
path: 'C:\\Users\\Desktop\\test\\upload\\9d2c67cb780b50409a3b25400',
fd: 3,
flags: 'w',
mode: 438,
start: undefined,
autoClose: true,
pos: undefined,
bytesWritten: 14,
closed: false,
[Symbol(kFs)]: [Object],
[Symbol(kCapture)]: false,
[Symbol(kIsPerformingIO)]: false
},
hash: null,
[Symbol(kCapture)]: false
}
}
从上述数据中看,并未发现有up_file.path
解决方案:
fs.rename(files.file.filepath, form.uploadDir +'/'+ files.file.originalFilename,err=>{
if(err) {
console.log("重命名失败");
console.log(err);
}else{
console.log("重命名成功!");
}
})
fs.rename参数说明
oldPath:files.file.filepath
newPath:form.uploadDir +‘/’+ files.file.originalFilename
callback:err=>{
if(err) {
console.log(“重命名失败”);
console.log(err);
}else{
console.log(“重命名成功!”);
}
}
其中newPath的取值我也做了修改,如果只用form.uploadDir则会报-4048错误
[Error: EPERM: operation not permitted, rename 'C:\Users\Desktop
\test\upload\b9f3978adae3beff6d690ef00' -> 'C:\Users\Desktop\test\upload'] {
errno: -4048,
code: 'EPERM',
syscall: 'rename',
path: 'C:\\Users\\Desktop\test\\upload\\b9f3978adae3beff6d690ef00',
dest: 'C:\\Users\\Desktop\\test\\upload'
}