Search code examples
javagoogle-cloud-storage

How can I set pageToken to get item lists from Google Cloud Storage via Java SDK?


I want to set pageToken to get items stored at Google Cloud Storage. I'm using Google API Client Library for Java v1.19.x.

I have no idea to generate pageToken from file path(or file name).

2 files stored in bucket.

  • my-bucket
    • /test.csv
    • /test2.csv

When I tried Google APIs Explorer with following parameters, I could get nextPageToken Cgh0ZXN0LmNzdg==.

And I found out that I can get test.csv string by decoding nextPageToken with base64.

  • bucket: my-bucket
  • pageToken:
  • prefix: test
  • maxResults: 1

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

But How can I get Cgh0ZXN0LmNzdg== from test.csv?

Although I tried Base64 encoding, result didn't match.

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);

Solution

  • I could get next token from file path string using following codes by myself.

    How to get nextToken from path string

    String nextToken = base64encode(0x0a + asciiCode + pathString)

    asciiCode can be taken between 0x01(SOH) and 0x7f(DEL). It seems to depend on path length.

    • my-bucket/
      • a/a(3byte) 0x03
      • a/ab(4byte) 0x04
      • test.txt(8byte) 0x08

    Notice

    If path length is longer than 1024 byte, another rule seems to apply. But I couldn't found out rules.

    See also 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;
    }