如何从BlobResult []获取Blob名称?

时间:2019-07-12 04:12:34

标签: javascript node.js azure blob azure-storage

我想删除我的azure blob存储中的所有文件。为此,我使用 listBlobsSegmented()列出了存储中的所有blob,然后将结果传递到 deleteBlobIfExists()中。但是 list BlobsSegment()中的参数blob.name没有正确分配。如何正确获取Blob名称?

这是存储模式:

const blobService = azure.createBlobService(accountName, accessKey, host); 
const containerName = 'container';

module.exports.listAll = () => {
    return new Promise(function(resolve, reject) {
        blobService.listBlobsSegmented(containerName, null, function(err, listBlobsResult) {
            if (err) {
                reject(err);
            } else {
                resolve(listBlobsResult);
            }
        });
    });
}

module.exports.delete = (blobName) => {
    return new Promise(function(resolve, reject) {
        blobService.deleteBlobIfExists(containerName, blobName, function(err, result) {
            if (err) {
                reject(err);
            } else {
                resolve({ message: `Block blob '${blobName}' deleted` });
            }
        })
    })
}

这就是我使用它们的方式:

const azureStorage = require('./storage-model')

router.get('/listAll', function(req, res) {
    azureStorage.listAll().then((listBlobsResult) => {
        console.log(listBlobsResult);
        res.send(listBlobsResult);
    }).catch((err) => {
        console.log(err);
    });
});

router.get('/deleteAll', function(req, res) {
    azureStorage.listAll().then((listBlobsResult) => {
        var responseBody;
        for (blob in listBlobsResult.entries) {
            azureStorage.delete(blob.name).then((result) => {
                console.log(result);
                responseBody += result;
            }).catch((err) => {
                console.log(err);
            });
        }
        res.send(responseBody);
    }).catch((err) => {
        console.log(err);
    });
})

这样做之后,它给了我错误消息

  

ArgumentNullError:函数所需的参数blob   未定义deleteBlobIfExists

以下是Microsoft的一些参考资料 deleteBlobIfExists() listBlobsSegmented() ListBlobsResult BlobResult

我发现blob.name仅返回blob索引号,而不返回实际的blob名称。有没有人可以帮助我?谢谢!


这是 listBlobsResult.entries 的样子:

[ {previous blob result},
 BlobResult {
    name: 'my_container/some_picture.jpg',
    creationTime: 'Thu, 11 Jul 2019 09:33:20 GMT',
    lastModified: 'Thu, 11 Jul 2019 09:33:20 GMT',
    etag: '0x8D705A4CFCB5528',
    contentLength: '6300930',
    contentSettings:
     { contentType: 'application/octet-stream',
       contentEncoding: '',
       contentLanguage: '',
       contentMD5: 'OyHfg8c3irniQzyhtCBdrw==',
       cacheControl: '',
       contentDisposition: '' },
    blobType: 'BlockBlob',
    lease: { status: 'unlocked', state: 'available' },
    serverEncrypted: 'true' },
 {next blob result},
 ...{many others blob result}]

我期望的是,我可以使用 blob.name 从listBlobsResult.entries的迭代中从条目blob中获取blob名称。但这给了我迭代的索引。

3 个答案:

答案 0 :(得分:1)

listBlobsResult.entries的类型为BlobResult[]

而且,for循环有两种类型,人们将它们混为一谈是很普遍的。

用于...中

for (let index in listBlobsResult.entries) {
    let blob = listBlobsResult.entries[index];

    /* ... do the work */
}

用于...的

for (let blob of listBlobsResult.entries) {
    /* ... do the work */
}

答案 1 :(得分:1)

您的代码中有两个问题。

  1. 您的for...in回调函数中的router.get('/deleteAll', callback)语句。根据MDN文档for...in statementblob的{​​{1}}变量实际上是您所说的数组for (blob in listBlobsResult.entries)的数字索引,请参见下图。

    enter image description here

    要解决此问题,有两种解决方案。

    1.1。要使用for...of statement而不是listBlobsResult.entries,只需将关键字for...in statement更改为in,而无需进行其他更改,则of变量就是{{1} }对象。

    blob

    1.2。要将BlobResult函数用于Array对象,如Array object的MDN文档中的下图所示。

    enter image description here

    for (var blob of listBlobsResult.entries) {
        azureStorage.delete(blob.name).then((result) => {
            console.log(result);
            responseBody += result;
        }).catch((err) => {
            console.log(err);
        });
    }
    
  2. 根据Azure官方文档map的{​​{3}}小节,如下图所示,您使用List the blobslistBlobsResult.entries.map((blob) => { azureStorage.delete(blob.name).then((result) => { console.log(result); responseBody += result; }).catch((err) => { console.log(err); }); }); 函数仅列出了其中的前5000个blob。通过传递How to upload, download, and list blobs using the client library for Node.js v2作为listAll参数值而不是列出所有Blob来创建一个容器。

    listBlobsSegmented(string, ContinuationToken, ErrorOrResult<ListBlobsResult>)

    因此,如果容器中有5000个以上的blob,则要列出所有blob,请首先传递null以获取前5000个blob和ContinuationToken,然后传递先前的null值函数listBlobsResult.continuationToken来获取接下来的5000个Blob,直到listBlobsResult.continuationToken的值为空。


更新:listBlobsSegmented

的实现
listBlobsResult.continuationToken

答案 2 :(得分:-2)

列出blob时有一个称为定界符的选项。示例代码:

blobService.listBlobsSegmentedWithPrefix('documents',null,null,{delimiter:'/'},(error,result,response)=>{
    console.log(result);
    console.log(response.body.EnumerationResults.Blobs.BlobPrefix);
})

使用定界符/,列出操作将返回两部分的结果。

  • 结果,包含容器根目录下的blob信息,例如文件名
  • 响应主体中的BlobPrefix,包含带分隔符的单级目录名称。

[ { Name: 'docx/' }, { Name: 'xlsx/' } ]

希望有帮助。