【问题标题】:How can I set pageToken to get item lists from Google Cloud Storage via Java SDK?如何设置 pageToken 以通过 Java SDK 从 Google Cloud Storage 获取项目列表?
【发布时间】:2016-02-05 23:51:52
【问题描述】:

我想设置 pageToken 以获取存储在 Google Cloud Storage 中的项目。我正在使用适用于 Java v1.19.x 的 Google API 客户端库。

我不知道从文件路径(或文件名)生成 pageToken。

存储在桶中的2个文件。

  • 我的桶
    • /test.csv
    • /test2.csv

当我尝试使用以下参数Google APIs Explorer 时,我可以得到 nextPageToken Cgh0ZXN0LmNzdg==

我发现可以通过base64解码nextPageToken得到test.csv字符串。

  • 桶:我的桶
  • 页面令牌:
  • 前缀:测试
  • 最大结果:1

{"kind": "storage#objects", "nextPageToken": "Cgh0ZXN0LmNzdg==", ...}

但是我怎样才能从test.csv 获得Cgh0ZXN0LmNzdg==

虽然我尝试过 Base64 编码,但结果不匹配。

import com.google.api.client.repackaged.org.apache.commons.codec.binary.Base64;

String lastFile = "test.csv"
String token = Base64.encodeBase64String(lastFile.getBytes());

String bucket = "my-bucket"
String prefix = "test"

Storage.Objects.List listObjects = client.objects().list(bucket);
listObjects.setPrefix(prefix);
listObjects.setPageToken(token);
long maxResults = 1;
listObjects.setMaxResults(maxResults);
do {
    Objects objects = listObjects.execute();
    List<StorageObject> items = objects.getItems();

    token = objects.getNextPageToken();
    listObjects.setPageToken(token);
} while (token != null);

【问题讨论】:

  • 你为什么要在第一个请求上设置页面令牌?您只需在后续请求中设置它。
  • 感谢您的评论。我的应用程序将最后一个文件名(下载成功)保存在本地配置文件中。如果下载下一个文件时出现错误,应用程序会尝试再次获取文件列表,下载完成的文件除外。
  • 我认为这行不通。页面令牌是一个不透明的标识符。不支持从特定对象恢复。
  • 如您所说,页面令牌似乎不透明。供您参考,当路径长度小于 128 字节时,我可以使用以下代码获取页面令牌。谢谢你。 private String base64Encode(String path) { byte[] encoding; byte[] utf8 = path.getBytes(Charsets.UTF_8);编码=新字节[utf8.length + 2];编码[0] = 0x0a; encoding[1] = new Byte(String.valueOf(path.length()));字符串 s = BaseEncoding.base64().encode(encoding);返回 s; }
  • @sakama 是否可以发布您的答案并接受它,以便其他人可以从中受益。谢谢

标签: java google-cloud-storage


【解决方案1】:

我可以自己使用以下代码从文件路径字符串中获取下一个令牌。

如何从路径字符串中获取 nextToken

字符串 nextToken = base64encode(0x0a + asciiCode + pathString)

asciiCode 可以在 0x01(SOH) 和 0x7f(DEL) 之间取值。它似乎取决于路径长度。

  • 我的桶/
    • a/a(3byte) 0x03
    • a/ab(4byte) 0x04
    • test.txt(8byte) 0x08

通知

如果路径长度超过 1024 字节,则似乎适用另一条规则。但我找不到规则。

另见Object Name Requirements

import com.google.common.io.BaseEncoding;

String lastFile = "test.csv"
String token = base64Encode(lastFile);

String bucket = "my-bucket"
String prefix = "test"

Storage.Objects.List listObjects = client.objects().list(bucket);
listObjects.setPrefix(prefix);
listObjects.setPageToken(token);
long maxResults = 1;
listObjects.setMaxResults(maxResults);
do {
    Objects objects = listObjects.execute();
    List<StorageObject> items = objects.getItems();

    token = objects.getNextPageToken();
    listObjects.setPageToken(token);
} while (token != null);

private String base64Encode(String path) {
    byte[] encoding;
    byte[] utf8 = path.getBytes(Charsets.UTF_8);
    encoding = new byte[utf8.length + 2];
    encoding[0] = 0x0a;
    encoding[1] = new Byte(String.valueOf(path.length()));
    String s = BaseEncoding.base64().encode(encoding);
    return s;
}

【讨论】:

    【解决方案2】:

    我知道这个问题已经回答并适用于 Java,我想提一下这个问题也适用于 PHP。

    在上面 sakama 批准的帖子的帮助下,我找到了他的解决方案的 PHP 版本。

    生成令牌的 PHP 等价物如下:
    base64_encode(pack('c', 0x0a) . pack('c', $path_string_length) . pack('a*', $path_string));

    字节模式确实(正如 sakama 已经提到的)是:
    &lt;line feed&gt;&lt;line data length&gt;&lt;line data&gt;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-03
      • 1970-01-01
      • 2020-01-24
      • 1970-01-01
      相关资源
      最近更新 更多