需求背景
最近接了一些比较难搞的需求,主要任务是把单子关联的附件下载到本地,然后上传至文档库和ftp。这些文件原始出处有minio,有在集群之外的其他服务器。上传过程要考虑不把系统打挂,控制好并发。受制于网络环境,文件太大容易失败。
解决办法
-
采用node 快速开发。 -
promise await 控制好并发 -
记录失败日志
思路
-
获取唯一标识 -
获取文件md5值 -
采用split-file分割文件 -
循环分割文件上传
代码
// npm install crypto
// npm install request
// npm install split-file
const fs = require('fs');
const request = require('request');
const crypto = require('crypto');
const splitFile = require('split-file');
let repoId = 685;
let targetFilePath = "test/";
let artiName = "CentOS-7-x86_64-DVD-2009.iso";
// 文件路径
let fileName = "D:/vm/CentOS-7-x86_64-DVD-2009.iso";
let operationName = "石磊";
let artiType = 1;
let baseUrl = 'http://url'
// Split file size in MB
let fileSplitSize = 64;
function getChecksum(path) {
return new Promise(function (resolve, reject) {
// crypto.createHash('sha1');
// crypto.createHash('sha256');
const hash = crypto.createHash('md5');
const input = fs.createReadStream(path);
input.on('error', reject);
input.on('data', function (chunk) {
hash.update(chunk);
});
input.on('close', function () {
resolve(hash.digest('hex'));
});
});
}
console.log("current file_split_size: " + fileSplitSize);
// Get upload identity
request.post({
url: baseUrl + '/uuid',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ 'repoId': repoId })
}, function (error, response, body) {
if (!error && response.statusCode == 200) {
let identityResult = JSON.parse(body);
let identity = identityResult.data;
console.info('identity: ', identity);
let splitFilePromise = splitFile.splitFileBySize(fileName, fileSplitSize * 1024 * 1024);
let md5Promise = getChecksum(fileName);
Promise.all([md5Promise, splitFilePromise])
.then(async results => {
let md5 = results[0];
let names = results[1];
for (let i = 0; i < names.length; i++) {
let tempPath = names[i];
console.log("tempPath: ", tempPath);
let formData = {
chunk: i,
chunks: names.length,
name: artiName,
md5: md5,
identity: identity,
repoId: repoId,
targetFilePath: targetFilePath,
artiName: artiName,
artiType: artiType,
operationName: operationName,
file: {
value: fs.createReadStream(tempPath),
options: {
filename: 'nameinpost',
contentType: 'multipart/form-data'
}
}
};
try {
await uploadFileChunk(formData);
} catch (err) {
console.error(err);
}
}
})
.catch(err => {
console.log(err);
});
}
});
async function uploadFileChunk(formData) {
console.log("start -formData: ", formData);
return new Promise((resolve, reject) => {
request.post({
url: baseUrl + '/api/uploadurl',
formData: formData
}, function (error, response, body) {
if (!error && response.statusCode == 200) {
let result = JSON.parse(body).data;
console.log("Link: " + result);
resolve(result);
} else {
console.log("Error from: ", formData);
console.error("Error: ", error);
reject(error);
}
});
});
}
总结
放弃问题就没收获!
原文始发于微信公众号(程序员石磊):基于node的文件分片上传
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/251434.html