首先是HTML5的几个规范
- File
- FileReader
- ArrayBuffer
- Blob
input上传的文件就是File类型文件,而File是基于Blob设计的。
接口自带slice方法,可以分割文件,达到分片上传的目的。
FileReader可以读取Blob里面的内容。
//将字符串转换成 Blob对象
var blob = new Blob(['中文字符串'], {
type: 'text/plain'
});
//将Blob 对象转换成字符串
var reader = new FileReader();
reader.readAsText(blob, 'utf-8');
reader.onload = function (e) {
console.info(reader.result);
}
使用方法如上,把上传文件接口类型设定为multipart/form-data,然后上传经过slice分片的文件。
node里可以用中间件解析文件,比如formidable、multer
const formidable = require('formidable');
app.use(formidable (
{
encoding: 'utf-8',
multiples: true, // req.files to be arrays of files
}
));
接口里可以用可读取流fs.createReadStream、读写文件操作文件,代码如下。
var fileInfo,
fileReceive;
app.post('/upload',function (req, res) {
console.log('files',req.files);
var file = req.files.file;
if(file && fileInfo.end < fileInfo.size){
fs.readFile(file.path,(err,data)=>{
if(err){
return console.error(err);
};
fileReceive = fileReceive ? Buffer.concat([fileReceive,data]) : data;
fileInfo.end += data.length;
if(fileInfo.end >= fileInfo.size){
fs.writeFile(fileInfo.name,fileReceive,()=>{
console.log('上传完成!');
});
};
res.send({progress: fileInfo.end / fileInfo.size});
});
}else{
res.send('error');
}
});
先获取文件总大小、文件名字等信息,然后每次接受到分片文件后对buffer进行合并并且保存已经接受到的文件大小,当接受完成后保存文件。
注这个方法需要node可操作的内存大于接受文件,否则就要每次接受分片文件时都读写一遍文件,不再node里进行缓存,但是这样比较费时。