基于node的文件分片上传

需求背景

最近接了一些比较难搞的需求,主要任务是把单子关联的附件下载到本地,然后上传至文档库和ftp。这些文件原始出处有minio,有在集群之外的其他服务器。上传过程要考虑不把系统打挂,控制好并发。受制于网络环境,文件太大容易失败。

解决办法

  • 采用node 快速开发。
  • promise await 控制好并发
  • 记录失败日志

思路

  1. 获取唯一标识
  2. 获取文件md5值
  3. 采用split-file分割文件
  4. 循环分割文件上传

代码

// 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' },
    bodyJSON.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

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!