如何用Go实现Azure Blob存储的层级Blob列表遍历?
问题:Go语言遍历Azure Blob存储顶层目录无结果
在Python中,可通过以下代码遍历Blob存储的顶层“目录”:
container_client.walk_blobs(name_starts_with=path + "/", delimiter="/")
尝试用Go语言实现相同功能,代码如下:
func getModelsHierarchy(client *azblob.Client, containerName string, directory string) { maxResults := int32(200) delimiter := "/" containerClient := client.ServiceClient().NewContainerClient(containerName) pager := containerClient.NewListBlobsHierarchyPager(delimiter, &container.ListBlobsHierarchyOptions{ Include: container.ListBlobsInclude{}, MaxResults: &maxResults, Prefix: &directory, }) for pager.More() { resp, err := pager.NextPage(context.TODO()) if err != nil { log.Fatal(err) } for _, blob := range resp.ListBlobsHierarchySegmentResponse.Segment.BlobItems { fmt.Println("Adding model " + *blob.Name) } } }
在Blob存储和开启层级命名空间的Data Lake Gen2中测试,且已通过Web存储资源管理器确认存在文件和目录,但结果异常:使用"/"作为分隔符时无返回结果,使用"_"作为分隔符时返回所有文件。
原因分析
- 未处理目录前缀(BlobPrefixes):使用
"/"作为分隔符时,Azure Blob服务会将目录以BlobPrefix的形式返回,而非BlobItem。原代码仅遍历BlobItems(对应文件),若顶层只有目录没有文件,就会无输出。 - Prefix格式不匹配:Python代码中使用
path + "/"作为前缀,而Go代码直接传入directory参数。若directory未以"/"结尾,会导致前缀匹配逻辑与Python不一致,无法正确筛选目标路径下的顶层内容。
修复后的代码
import ( "context" "fmt" "log" "strings" "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/container" "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob" ) func getModelsHierarchy(client *azblob.Client, containerName string, directory string) { maxResults := int32(200) delimiter := "/" // 对齐Python逻辑:确保前缀以"/"结尾(若directory非空) if directory != "" && !strings.HasSuffix(directory, delimiter) { directory += delimiter } containerClient := client.ServiceClient().NewContainerClient(containerName) pager := containerClient.NewListBlobsHierarchyPager(delimiter, &container.ListBlobsHierarchyOptions{ MaxResults: &maxResults, Prefix: &directory, }) for pager.More() { resp, err := pager.NextPage(context.TODO()) if err != nil { log.Fatal(err) } // 遍历顶层文件(BlobItems) for _, blob := range resp.Segment.BlobItems { fmt.Println("Adding file: " + *blob.Name) } // 遍历顶层目录(BlobPrefixes) for _, prefix := range resp.Segment.BlobPrefixes { fmt.Println("Adding directory: " + *prefix.Name) } } }
关键说明
- Prefix格式修正:给
directory添加结尾的"/",与Python代码中path + "/"的筛选逻辑完全对齐,确保只返回目标路径下的顶层内容。 - 新增BlobPrefixes遍历:目录结构通过
BlobPrefixes返回,加入这部分遍历后,就能正确获取到顶层目录。 - 移除冗余Include参数:原代码中
Include: container.ListBlobsInclude{}为默认值,可省略不写。
内容的提问来源于stack exchange,提问作者Ways
相关产品推荐
相关产品推荐

