You need to enable JavaScript to run this app.
导航
列举分层命名空间内对象(Java SDK)
最近更新时间:2024.08.01 17:46:09首次发布时间:2024.08.01 17:46:09

分层命名空间 HNS(Hierarchical NameSpace,简称分层桶)是对象存储 TOS 推出的一个全新的基于分层元数据管理的桶类型。在提供分层命名空间能力的同时兼顾了对象扁平化扩展性,提供对象语义与文件语义透明互通的能力,实现真正的一份数据多种访问协议,提升数据使用效率。
相比原来扁平命名空间 FNS(Flat NameSpace,简称扁平桶)可以很好的支持目录级别的 mv 与 rename 操作,同时优化常见读操作 List 与目录 Head,提升数据处理效率与性能,能很好的满足大数据、数据湖和 AI 领域的使用场景。
本文介绍如何通过 TOS Java SDK 的 listObjects 接口列举指定目录下的对象和子目录等。

注意事项

  • 使用列举分层命名空间对象必须携带 delimiter,且只能使用目录分隔符 /
  • 列举对象前,您的账号必须具备 tos:ListBucket 权限,具体操作请参见 IAM 策略概述
  • 当前 TOS 已支持新的 listObjectsType2 接口,使用方式与 listObjects 接口基本一致。强烈建议您使用 listObjectsType2 接口,以获得更高的列举效率。具体使用方法请参见列举对象 V2

参数说明

listObjects 接口支持的参数如下。

参数

描述

prefix

本次查询结果的前缀。

delimiter

对对象名称进行分组的字符,列举分层命名空间对象必须携带 delimiter,且只能使用目录分隔符 /

marker

此次列举对象的起点。初始为 null,后续可取值为上次请求返回的 nextMarker。

maxKeys

返回列举对象的最大数。一次最多返回 1000 条结果,若不设置则默认返回 1000 条。

encodingType

对返回的内容进行编码并指定编码的类型。

示例代码

列举指定目录下的文件和子目录

分层桶按照全新的分层架构来组织元数据,因此具有目录实体。
通过 DelimiterPrefix 两个参数实现目录列举的功能:

  • 首先设置 Delimiter/ 同时设置 Prefix 为空, 可返回根目录下的对象和子目录信息。
  • 再设置 Delimiter/ 同时设置 Prefix 为子目录(commonPrefixes), 可返回子目录的对象和次级目录。

以下代码展示如何列举桶 bucket-example 根目录下的对象和子目录。

import com.volcengine.tos.TOSV2;
import com.volcengine.tos.TOSV2ClientBuilder;
import com.volcengine.tos.TosClientException;
import com.volcengine.tos.TosServerException;
import com.volcengine.tos.model.object.*;

public class HNSListObjectsExample {
    public static void main(String[] args) {
        String endpoint = "your endpoint";
        String region = "your region";
        String accessKey = System.getenv("TOS_ACCESS_KEY");
        String secretKey = System.getenv("TOS_SECRET_KEY");

        String bucketName = "bucket-example";
        int maxKeys = 10;
        String delimiter = "/";

        TOSV2 tos = new TOSV2ClientBuilder().build(region, endpoint, accessKey, secretKey);
        try{
            boolean isTruncated = true;
            String marker = null;
            while (isTruncated) {
                ListObjectsV2Input input = new ListObjectsV2Input().setBucket(bucketName)
                        .setMaxKeys(maxKeys).setDelimiter(delimiter).setMarker(marker);
                ListObjectsV2Output output = tos.listObjects(input);
                System.out.printf("listObjects succeed, is truncated? %b, next marker is %s.\n",
                        output.isTruncated(), output.getNextMarker());
                if (output.getContents() != null) {
                    for (int i = 0; i < output.getContents().size(); i++) {
                        ListedObjectV2 object = output.getContents().get(i);
                        System.out.printf("Listed object, key is %s, size is %d, storageClass is %s, ETag is %s, " +
                                        "last modified is %s, crc64 value is %s.\n", object.getKey(), object.getSize(),
                                object.getStorageClass(), object.getEtag(), object.getLastModified().toString(), object.getHashCrc64ecma());
                    }
                }
                if (output.getCommonPrefixes() != null) {
                    for (int i = 0; i < output.getCommonPrefixes().size(); i++) {
                        ListedCommonPrefix commonPrefix = output.getCommonPrefixes().get(i);
                        System.out.println("Listed commonPrefix is " + commonPrefix.getPrefix());
                        // commonPrefix 为子目录,可用其作为 prefix 参数继续往下列举
                        listCommonPrefix(bucketName, maxKeys, delimiter, commonPrefix.getPrefix(), tos);
                    }
                }
                isTruncated = output.isTruncated();
                marker = output.getNextMarker();
            }
        } catch (TosClientException e) {
            // 操作失败,捕获客户端异常,一般情况是请求参数错误,此时请求并未发送
            System.out.println("listObjects failed");
            System.out.println("Message: " + e.getMessage());
            if (e.getCause() != null) {
                e.getCause().printStackTrace();
            }
        } catch (TosServerException e) {
            // 操作失败,捕获服务端异常,可以获取到从服务端返回的详细错误信息
            System.out.println("listObjects failed");
            System.out.println("StatusCode: " + e.getStatusCode());
            System.out.println("Code: " + e.getCode());
            System.out.println("Message: " + e.getMessage());
            System.out.println("RequestID: " + e.getRequestID());
        } catch (Throwable t) {
            // 作为兜底捕获其他异常,一般不会执行到这里
            System.out.println("listObjects failed");
            System.out.println("unexpected exception, message: " + t.getMessage());
        }
    }

    private static void listCommonPrefix(String bucketName, int maxKeys, String delimiter, String prefix, TOSV2 tos) {
        boolean isTruncated = true;
        String marker = null;
        while (isTruncated) {
            ListObjectsV2Input input = new ListObjectsV2Input().setBucket(bucketName).setMaxKeys(maxKeys)
                    .setDelimiter(delimiter).setMarker(marker).setPrefix(prefix);
            ListObjectsV2Output output = tos.listObjects(input);
            System.out.printf("listObjects succeed, is truncated? %b, next marker is %s.\n",
                    output.isTruncated(), output.getNextMarker());
            if (output.getContents() != null) {
                for (int i = 0; i < output.getContents().size(); i++) {
                    ListedObjectV2 object = output.getContents().get(i);
                    System.out.printf("Listed object, key is %s, size is %d, storageClass is %s, ETag is %s, " +
                                    "last modified is %s, crc64 value is %s.\n", object.getKey(), object.getSize(),
                            object.getStorageClass(), object.getEtag(), object.getLastModified().toString(), object.getHashCrc64ecma());
                }
            }
            if (output.getCommonPrefixes() != null) {
                for (int i = 0; i < output.getCommonPrefixes().size(); i++) {
                    ListedCommonPrefix commonPrefix = output.getCommonPrefixes().get(i);
                    System.out.println("Listed commonPrefix is " + commonPrefix.getPrefix());
                }
            }
            isTruncated = output.isTruncated();
            marker = output.getNextMarker();
        }
    }
}

相关文档

关于列举对象的 API 文档,请参见 ListObjects