在Express JS中下载多个Blob?

时间:2018-08-11 10:42:40

标签: javascript node.js azure express azure-storage-blobs

我正在使用Express JS制作Web应用程序。我正在使用的存储是Azure Blob。存储结构类似于patient/date/time/images/1.jpg .. 1000.jpg

我需要在患者个人资料旁边有一个下载按钮,他们将只能从patient/文件夹中下载数据。是否有任何功能可以让您使用前缀选项getBlobToStream

谢谢。

1 个答案:

答案 0 :(得分:1)

将此代码段另存为storageoper.js。添加您的连接字符串。

const azure = require('azure-storage');
const archiver = require('archiver');
const storageConnectionString = 'xxx';
const blobService = azure.createBlobService(storageConnectionString);

let prefix = "";
let container = "";
let continuationToken = null;
let blobCount = 0;
let blobResults = [];
let parallelrequest = 100;

// list at most 5000 blobs once
const listBlobsSegmented = () => {
    return new Promise((resolve, reject) => {
        blobService.listBlobsSegmentedWithPrefix(container, prefix, continuationToken, (err, results) => {
            if (err) {
                reject(err);
            } else {
                continuationToken = results.continuationToken;
                blobResults = results.entries;
                resolve("done");
            }
        });
    });
};

const zipOneBlob = (blobName) => {
    return new Promise((resolve, reject) => {
        blobService.createReadStream(container, blobName, err => {
            if (err) {
                reject(err);
            }
        }).on('data', data => {
            zip.append(data, { name: blobName });
            resolve("done");
        }).on('error', err => {
            reject(err);
        });
    });
};

// restrict parallel count of request to storage
const zipBlobsSegmented = (var1, var2) => {

    let zippedCount = var1;
    let leftCount = var2;

    let promises = [];
    let length = leftCount < parallelrequest ? leftCount : parallelrequest;

    for (let i = zippedCount; i < length + zippedCount; i++) {
        let promise = zipOneBlob(blobResults[i].name);
        promises.push(promise);
    }
    return Promise.all(promises).then(() => {
        zippedCount += length;
        leftCount -= length;
        return leftCount > 0 ? zipBlobsSegmented(zippedCount, leftCount) : Promise.resolve();
    });
};

// list and download
const listAndDownloadBlobs = () => {
    return listBlobsSegmented().then(() => {
        return zipBlobsSegmented(0, blobResults.length);
    }).then(() => {
        blobCount += blobResults.length;
        return continuationToken ? listAndDownloadBlobs() : Promise.resolve();
    }).catch(err => {
        console.log(err);
    });
};

let zip = archiver('zip').on('error', error => {
    console.log(error);
});


module.exports.createZipFromBlobs = (res, containerName, blobPrefix, parallelRequestCount = 100) => {
    container = containerName;
    prefix = blobPrefix;
    parallelrequest = parallelRequestCount;
    zip.pipe(res);
    listAndDownloadBlobs().then(() => {
        zip.finalize();
        console.log(`total ${blobCount} files downloaded`);
    });
};

将其放入您的Web应用程序并将其作为模块导入。(还需要安装存档器模块)。

var storageoper = require('[specify relative path]/storageoper');

然后在您的应用处理程序中调用该方法。

res.attachment(`${containerName}.zip`);
storageoper.createZipFromBlobs(res, containerName, prefix);