CloudBlockBlob的URI在c#

时间:2019-06-19 09:22:06

标签: c# azure azure-storage-blobs

我有简单的代码可以与Azure Blob交互,如下所示。
我想获取上传文件的URL。
假设如果在我的Blob存储中,我有一个容器,其中有多个文件夹,则需要获取文件的路径,因此要尝试使用blockBlob.Uri参数。

using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
using System;
using System.IO;
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {         
            string   storageAccConnString = "Connection string";
            CloudStorageAccount storageAccount = "Account Name";
            CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
            string folderPath    "Folder1" + Path.DirectorySeparatorChar + "Folder2" + Path.DirectorySeparatorChar + "Folder3";
            CloudBlobContainer container = blobClient.GetContainerReference(folderPath);
            CloudBlockBlob blockBlob = container.GetBlockBlobReference("Local system filePath which needs to be uploaded to Blob");
            Console.WriteLine("URI : " + blockBlob.Uri);
            Console.WriteLine("URI : " + blockBlob.Uri.ToString());
            Console.WriteLine("URI : " + blockBlob.Uri.OriginalString);
            Console.ReadLine();  
            // I didnt write the upload code as my question was regarding URI
        }
    }
}

我得到了响应,但是我得到了/,而不是像“ \或” %5C“这样的文件夹分隔符。

  

URI:   https://storageaccountname.blob.core.windows.net/Folder1%5CFolder2%5Folder3/Test.zip

我该如何纠正。任何帮助都会有用。谢谢。

5 个答案:

答案 0 :(得分:1)

您的代码存在一些问题:

  • 首先,blob存储具有2级层次结构:容器和blob。您创建容器引用的方式不正确。因为您的容器名称包含URL保留字符(\),所以它的URL编码为%5C
  • 接下来,如果要在容器中的虚拟文件夹中上载文件,则需要将虚拟文件夹的路径附加到Blob的名称上。例如,假设您有一个名为files的blob容器,并且想要上传一个名为myfile.txt的文件,但是将其放置在Folder1/Folder2/Folder3虚拟文件夹中,这是您要执行的操作:< / li>
static void Main(string[] args)
{         
    string   storageAccConnString = "Connection string";
    CloudStorageAccount storageAccount = "Account Name";
    CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();       
    CloudBlobContainer container = blobClient.GetContainerReference('files');
    var blobName = "Folder1/Folder2/Folder3" + "myfile.txt";
    CloudBlockBlob blockBlob = container.GetBlockBlobReference(blobName);
    Console.WriteLine("URI : " + blockBlob.Uri);
    Console.WriteLine("URI : " + blockBlob.Uri.ToString());
    Console.WriteLine("URI : " + blockBlob.Uri.OriginalString);
    Console.ReadLine();  
    // I didnt write the upload code as my question was regarding URI
}

答案 1 :(得分:1)

Blob存储并不真正使用文件夹和子文件夹。它仅使用文件路径作为完整文件名。您所拥有的只是将容器作为一种分离机制。 您可以上载带有文件夹分隔符的文件,但是即使支持blob存储的文件浏览器通常会模拟这些文件夹,也不会做太多事情。 您只需在文件名中包含文件路径即可模拟文件的位置。 是否要将文件移动到其他目录?只需重命名文件路径,等等。

如果需要,可以通过以下方式解码URL:

    string input = "https://storageaccountname.blob.core.windows.net/Folder1%5CFolder2%5Folder3/Test.zip";
    string decoded = HttpUtility.UrlDecode(input);
    Console.WriteLine(decoded);

答案 2 :(得分:0)

查看您的代码,看来您正在使用System.IO.Path.DirectorySeparatorChar,该代码(根据Microsoft docs)将:

  

在用于反映分层文件系统组织的路径字符串中提供用于分隔目录级别的特定于平台的字符。

在Windows系统上运行时,DirectorySeparatorChar\,而在Linux系统上则是/

向Web服务发出请求时,用于URI的路径分隔符为/,而\被认为是不安全的字符,需要进行编码-因此,您会看到%5C。 / p>

要解决您面临的问题,最简单的解决方案是将Path.DirectorySeparatorChar的用法替换为"/"

string folderPath = "Folder1/Folder2/Folder3";

答案 3 :(得分:0)

问题是您要查询其中包含目录分隔符的容器引用。容器仅用于在根级别将blob分组在一起。

  

一个容器组织了一组Blob,类似于文件系统中的目录。一个存储帐户可以包含无限数量的容器,并且一个容器可以存储无限数量的Blob。

来源:Introduction to Azure Blob storage

Blob中可以包含目录分隔符,将它们组织在容器内部的虚拟文件夹中。

有关如何执行此操作的更多信息,请参见Creating an Azure Blob Hierarchy

答案 4 :(得分:0)

请确保在保存这样的文件时

Stream str
...
CloudBlockBlob blob = container.GetBlockBlobReference(changePathCharacters(physicalRoute) + fileName);                        

blob.UploadFromStream(str);

physicalRoute 尚未用于文件夹分隔符的\\,它必须具有/分隔符:

private static string changePathCharacters(string path)
        {

            return path.Replace(@"\", @"/");
        }

然后在blockBlob.Uri.AbsoluteUri中,您将看到类似这样的内容:

https://storageaccountname.blob.core.windows.net/Folder1/Folder/Folder3/Test.zip