/* * Copyright 2013 Google Inc. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.appengine.demos; import com.google.appengine.tools.cloudstorage.GcsFileOptions; import com.google.appengine.tools.cloudstorage.GcsFilename; import com.google.appengine.tools.cloudstorage.GcsInputChannel; import com.google.appengine.tools.cloudstorage.GcsOutputChannel; import com.google.appengine.tools.cloudstorage.GcsService; import com.google.appengine.tools.cloudstorage.GcsServiceFactory; import com.google.appengine.tools.cloudstorage.RetryParams; import com.google.appengine.tools.development.testing.LocalBlobstoreServiceTestConfig; import com.google.appengine.tools.development.testing.LocalDatastoreServiceTestConfig; import com.google.appengine.tools.development.testing.LocalServiceTestHelper; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.nio.ByteBuffer; import java.nio.channels.Channels; import java.util.Arrays; import java.util.HashMap; import java.util.Map; /** * https://developers.google.com/appengine/docs/java/googlecloudstorageclient/getstarted * * @author yuriyz on 8/6/14. */ public class LocalExample { /** * Use this to make the library run locally as opposed to in a deployed servlet. */ LocalServiceTestHelper helper = new LocalServiceTestHelper( new LocalBlobstoreServiceTestConfig(), new LocalDatastoreServiceTestConfig()); /** * This is the service from which all requests are initiated. * The retry and exponential backoff settings are configured here. */ private final GcsService gcsService = GcsServiceFactory.createGcsService(RetryParams.getDefaultInstance()); /** * Writes the provided object to the specified file using Java serialization. One could use * this same technique to write many objects, or with another format such as Json or XML or just a * DataOutputStream. * * Notice at the end closing the ObjectOutputStream is not done in a finally block. * See below for why. */ private void writeObjectToFile(GcsFilename fileName, Object content) throws IOException { GcsOutputChannel outputChannel = gcsService.createOrReplace(fileName, GcsFileOptions.getDefaultInstance()); @SuppressWarnings("resource") ObjectOutputStream oout = new ObjectOutputStream(Channels.newOutputStream(outputChannel)); oout.writeObject(content); oout.close(); } /** * Writes the byte array to the specified file. Note that the close at the end is not in a * finally.This is intentional. Because the file only exists for reading if close is called, if * there is an exception thrown while writing the file won't ever exist. (This way there is no * need to worry about cleaning up partly written files) */ private void writeToFile(GcsFilename fileName, byte[] content) throws IOException { @SuppressWarnings("resource") GcsOutputChannel outputChannel = gcsService.createOrReplace(fileName, GcsFileOptions.getDefaultInstance()); outputChannel.write(ByteBuffer.wrap(content)); outputChannel.close(); } /** * Reads an object from the specified file using Java serialization. One could use this same * technique to read many objects, or with another format such as Json or XML or just a * DataInputStream. * * The final parameter to openPrefetchingReadChannel is a buffer size. It will attempt to buffer * the input by at least this many bytes. (This must be at least 1kb and less than 10mb) If * buffering is undesirable openReadChannel could be called instead, which is totally unbuffered. */ private Object readObjectFromFile(GcsFilename fileName) throws IOException, ClassNotFoundException { GcsInputChannel readChannel = gcsService.openPrefetchingReadChannel(fileName, 0, 1024 * 1024); try (ObjectInputStream oin = new ObjectInputStream(Channels.newInputStream(readChannel))) { return oin.readObject(); } } /** * Reads the contents of an entire file and returns it as a byte array. This works by first * requesting the length, and then fetching the whole file in a single call. (Because it calls * openReadChannel instead of openPrefetchingReadChannel there is no buffering, and thus there is * no need to wrap the read call in a loop) * * This is really only a good idea for small files. Large files should be streamed out using the * prefetchingReadChannel and processed incrementally. */ private byte[] readFromFile(GcsFilename fileName) throws IOException { int fileSize = (int) gcsService.getMetadata(fileName).getLength(); ByteBuffer result = ByteBuffer.allocate(fileSize); try (GcsInputChannel readChannel = gcsService.openReadChannel(fileName, 0)) { readChannel.read(result); } return result.array(); } /** * Writes a map to GCS and then reads it back printing the result to standard out. * Then does the same for a byte array. * (You may wish to suppress stderr as there is a lot of noise) */ public static void main(String[] args) throws IOException, ClassNotFoundException { LocalExample example = new LocalExample(); example.helper.setUp(); try { /** Write and read back a map */ GcsFilename filename = new GcsFilename("MyBucket", "foo"); Map<String, String> mapContent = new HashMap<>(); mapContent.put("foo", "bar"); example.writeObjectToFile(filename, mapContent); System.out.println("Wrote " + mapContent + " read: " + example.readObjectFromFile(filename)); /** Write and read back a byteArray */ byte[] byteContent = new byte[] {1, 2, 3, 4, 5}; example.writeToFile(filename, byteContent); System.out.println("Wrote " + Arrays.toString(byteContent) + " read: " + Arrays.toString(example.readFromFile(filename))); } finally { example.helper.tearDown(); } } }