Tom Jonckheere
Tom Jonckheere

Reputation: 1648

How to download a file from Google Cloud Storage with Java?

I'm developping an application that provides users with an interface where they can download files from our Google Cloud Storage. I wrote unit tests and I could connect to the storage and a file was downloaded.

Now that I'm (almost) finished with my interface, I wanted to test the whole application. But now I notice I don't really download the file, I download a file with META data about the file I want to download. Something like:

{
 "kind": "storage#object",
 "id": "xxxxxxxxxxx/Homer.png/xxxxxxxxxxxx",
 "selfLink": "https://www.googleapis.com/storage/xxxxxxxxxxxxxxxx/Homer.png",
 "name": "Homer.png",
 "bucket": "xxxxxxxxxxxxxxx",
 "generation": "xxxxxxxxxxxxxxx",
 "metageneration": "1",
 "contentType": "image/png",
 "updated": "2014-07-17T08:37:28.026Z",
 "storageClass": "STANDARD",
 "size": "xxxxx",
 "md5Hash": "xxxxxxxxxxxxxxxxxxxxx",
 "mediaLink": "https://www.googleapis.com/download/storage/xxxxxxxxxxxxxxx/o/Homer.png?generation=xxxxxxxxxxxxxxxxx&alt=media",
 "owner": {
  "entity": "user-xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "entityId": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
 },
 "crc32c": "xxxxxxxxxx",
 "etag": "xxxxxxxxxxxxx"
}

I'm wondering what I'm doing wrong, this is the code I'm using to download the file:

public byte[] getFileAsByteArray(String bucketName, String fileName)
        throws GoogleAppManagerException {
        Storage storage = null;
        try {
            storage = getStorage();
        } catch (GeneralSecurityException e) {
            throw new GoogleAppManagerException(SECURITY_EXCEPTION + e.getStackTrace(), e);
        } catch (IOException e) {
            throw new GoogleAppManagerException(IO_EXCEPTION + e.getStackTrace(), e);
        }
        Get get = null;
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try {
            get = storage.objects().get(bucketName, fileName);
            get.executeAndDownloadTo(outputStream);
        } catch (IOException e1) {
            throw new GoogleAppManagerException(IO_EXCEPTION + e1.getStackTrace(), e1);
        }
        return outputStream.toByteArray();
    }

Upvotes: 5

Views: 27718

Answers (3)

user6259970
user6259970

Reputation:

With the latest libraries :

Storage storage = StorageOptions.newBuilder()
            .setProjectId(projectId)
            .setCredentials(GoogleCredentials.fromStream(new FileInputStream(serviceAccountJSON)))
            .build()
            .getService();
Blob blob = storage.get(BUCKET_URL, RELATIVE_OBJECT_LOCATION);
ReadChannel readChannel = blob.reader();
FileOutputStream fileOutputStream = new FileOutputStream(outputFileName);
fileOutputStream.getChannel().transferFrom(readChannel, 0, Long.MAX_VALUE);
fileOutputStream.close();

Upvotes: 11

Mayur Mamoria
Mayur Mamoria

Reputation: 31

@AnandMohan is correct. You just have to make copy on "tmp" folder because all the locations are read only, just "tmp" is writable. Check below:

    Storage storage = StorageOptions.newBuilder().setProjectId(PROJECT_ID).build().getService();
    Blob blob = storage.get(BUCKET_NAME, fileName);
    ReadChannel readChannel = blob.reader();
    File file = new File("/tmp/" + FILE_NAME);
    FileOutputStream fileOuputStream = new FileOutputStream(file);
    fileOuputStream.getChannel().transferFrom(readChannel, 0, Long.MAX_VALUE);
    fileOuputStream.close();
    // Now file is ready to send whereever you want

Upvotes: 3

jterrace
jterrace

Reputation: 67063

As you say, currently you're downloading the metadata. You need to use media download to download the object's data.

Take a look at the sample Java code here: https://developers.google.com/storage/docs/json_api/v1/objects/get

That is the simplest method, using getMediaHttpDownloader().

There is more info on media and the other method, resumable download, here: https://code.google.com/p/google-api-java-client/wiki/MediaDownload

Upvotes: 3

Related Questions