将文件保存到 Azure Blob 存储的奇怪行为

Posted

技术标签:

【中文标题】将文件保存到 Azure Blob 存储的奇怪行为【英文标题】:Strange behavior saving a file into Azure blob storage 【发布时间】:2021-12-08 02:38:42 【问题描述】:

我正在使用 @azure/storage-blob:^12.8.0, @azure/storage-queue: ^12.7.0 包进行身份验证并连接到 Azure blob 存储,身份验证通过托管身份和目标授予访问权限 Storage Blob Data Contributor 角色,下面是我的代码

const credentialOptions = 
    managedIdentityClientId: process.env.MANAGED_IDENTITY_CLIENT_ID
;

const CONTAINER_NAME = 'C1';
const credential = new DefaultAzureCredential(credentialOptions);
const blobSvc = new BlobServiceClient(process.env.STORAGE_HOST, credential);
const containerClient = blobSvc.getContainerClient(CONTAINER_NAME);

export const store = async (file: string, folder: string) =>     
    const fileName = path.basename(file);
    const blob = `$folder/$fileName`;
    try 
        console.debug(`starting store $blob...`);      
        const blobClient = containerClient.getBlockBlobClient(blob);
        await blobClient.uploadFile(file);
        console.debug('store done.');
        return blob;
    
    catch (err) 
        console.error(err);       
        throw Error(err);
    
;


// in other module 
import store from 'BlobStorageHelper';

store('folder1/folder2/folder3', '/temporary/path/to/the/file.jpg');

一切正常,除了文件存储在错误的位置,例如,通过调用 store('folder1/folder2/folder3', 'path/file.jpg') 我希望文件存储在 folder1/folder2/folder3/file.jpg 但文件存储在 C1/folder1/folder2/folder3/file.jpg C1 是错误的容器名称,不应该发生,代码作为 Azure 函数节点运行。

说清楚,期望是

C1(容器) 文件夹 1 文件夹2 文件夹 3 文件.jpg

但实际结果是

C1(容器) C1 文件夹 1 文件夹2 文件夹 3 文件.jpg

有什么想法吗?

【问题讨论】:

这实际上是正确的行为。 Blob 将始终存储在容器中。 @GauravMantri 是的,但我猜你没有正确理解这个问题,文件总是存储在一个容器中,但是 blob 的路径不应该包含容器的名称,最后,文件存储在容器中,但容器的名称在 blob 的路径中重复。 嗨@Bahram,检查const blob = $folder/$fileName这个路径我认为你传递的容器名称以及文件夹结构 嗨@ShrutiJoshi-MT,这也是我的第一个猜测,但我检查了日志,console.debug('starting store $blob...'); 显示 blob 路径是正确的(没有容器名称)。我认为可能是 Azure API 弄乱了路径,但互联网上的大多数代码示例都表明代码很好。 您能否编辑您的问题并包含您如何调用store 方法的代码? 【参考方案1】:

尝试使用此代码,我在我的系统中尝试了此代码,能够将具有文件夹结构的文件存储在 azure 容器中

const blobServiceClient = BlobServiceClient.fromConnectionString("Connection String");
const containerClient = blobServiceClient.getContainerClient(containerName);
const blobName="test1/test2 "+ "/" + "test"
const blockBlobClient = containerClient.getBlockBlobClient(blobName);
const file="C: \\blobs\\test.txt"
await blockBlobClient.uploadFile(file);
console.log('\nUploading to Azure storage as blob:\n\t', blobName);

输出

文件保存在 azure storage 的容器中

【讨论】:

感谢分享,但我看到的唯一区别是您从ConnectionString 构造BlobServiceClient 而我使用HostCredentialToken 构造它,我认为这不相关问题,因为文件实际上存储在 blob 存储中。您的其余代码也与我的非常相似。 问题解决了吗?【参考方案2】:

问题是来自 AppSettings 的错误值在代码中并不明显。应该是https://accountname.blob.core.windows.net,但实际上是https://accountname.blob.core.windows.net/ContainerName

【讨论】:

以上是关于将文件保存到 Azure Blob 存储的奇怪行为的主要内容,如果未能解决你的问题,请参考以下文章

将 MemoryStream 文件存储到 Azure Blob

将最新的文件夹从 azure blob 存储加载到 azure 数据工厂

将 json 文档归档到 Azure Blob 存储的最佳做法是啥?

如何从 Azure Blob 存储将文件下载到浏览器

如何将字节数组(即 byte[])保存到 Azure Blob 存储?

使用 ADF 将 azure blob 文件复制到 azure synapse