Skip to content

Commit 4f454ad

Browse files
author
Sai Cheemalapati
committed
Add downloadTo to Blob
1 parent 2d5cbfe commit 4f454ad

2 files changed

Lines changed: 63 additions & 0 deletions

File tree

  • google-cloud-storage/src

google-cloud-storage/src/main/java/com/google/cloud/storage/Blob.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,15 @@
3434
import com.google.cloud.storage.spi.v1.StorageRpc;
3535
import com.google.common.base.Function;
3636
import com.google.common.io.BaseEncoding;
37+
38+
import java.io.FileOutputStream;
3739
import java.io.IOException;
3840
import java.io.ObjectInputStream;
3941
import java.net.URL;
42+
import java.nio.ByteBuffer;
43+
import java.nio.channels.Channels;
44+
import java.nio.channels.WritableByteChannel;
45+
import java.nio.file.Path;
4046
import java.security.Key;
4147
import java.util.Arrays;
4248
import java.util.List;
@@ -186,6 +192,26 @@ static Storage.BlobGetOption[] toGetOptions(BlobInfo blobInfo, BlobSourceOption.
186192
}
187193
}
188194

195+
/**
196+
* Downloads this blob to the given file path.
197+
*
198+
* @param path destination
199+
* @throws IOException upon failure
200+
*/
201+
public void downloadTo(Path path) throws IOException {
202+
FileOutputStream outputStream = new FileOutputStream(path.toFile());
203+
try (ReadChannel reader = reader()) {
204+
WritableByteChannel channel = Channels.newChannel(outputStream);
205+
ByteBuffer bytes = ByteBuffer.allocate(64 * 1024);
206+
while (reader.read(bytes) > 0) {
207+
bytes.flip();
208+
channel.write(bytes);
209+
bytes.clear();
210+
}
211+
}
212+
outputStream.close();
213+
}
214+
189215
/**
190216
* Builder for {@code Blob}.
191217
*/

google-cloud-storage/src/test/java/com/google/cloud/storage/BlobTest.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,14 @@
1616

1717
package com.google.cloud.storage;
1818

19+
import static org.easymock.EasyMock.anyObject;
1920
import static org.easymock.EasyMock.capture;
2021
import static org.easymock.EasyMock.createMock;
22+
import static org.easymock.EasyMock.createNiceMock;
2123
import static org.easymock.EasyMock.createStrictMock;
2224
import static org.easymock.EasyMock.eq;
2325
import static org.easymock.EasyMock.expect;
26+
import static org.easymock.EasyMock.getCurrentArguments;
2427
import static org.easymock.EasyMock.replay;
2528
import static org.easymock.EasyMock.verify;
2629
import static org.junit.Assert.assertArrayEquals;
@@ -43,11 +46,15 @@
4346
import com.google.common.io.BaseEncoding;
4447

4548
import org.easymock.Capture;
49+
import org.easymock.IAnswer;
4650
import org.junit.After;
4751
import org.junit.Before;
4852
import org.junit.Test;
4953

54+
import java.io.File;
5055
import java.net.URL;
56+
import java.nio.ByteBuffer;
57+
import java.nio.file.Files;
5158
import java.security.Key;
5259
import java.util.List;
5360
import java.util.Map;
@@ -517,4 +524,34 @@ public void testBuilder() {
517524
assertNull(blob.getUpdateTime());
518525
assertTrue(blob.isDirectory());
519526
}
527+
528+
@Test
529+
public void testDownloadTo() throws Exception {
530+
final byte[] expected = {1, 2};
531+
532+
initializeExpectedBlob(2);
533+
ReadChannel channel = createNiceMock(ReadChannel.class);
534+
expect(storage.getOptions()).andReturn(mockOptions);
535+
expect(storage.reader(BLOB_INFO.getBlobId())).andReturn(channel);
536+
replay(storage);
537+
// First read should return 2 bytes.
538+
expect(channel.read(anyObject(ByteBuffer.class)))
539+
.andAnswer(new IAnswer<Integer>() {
540+
@Override
541+
public Integer answer() throws Throwable {
542+
// Modify the argument to match the expected behavior of `read`.
543+
((ByteBuffer) getCurrentArguments()[0]).put(expected);
544+
return 2;
545+
}
546+
});
547+
// Second read should return 0 bytes.
548+
expect(channel.read(anyObject(ByteBuffer.class))).andReturn(0);
549+
replay(channel);
550+
initializeBlob();
551+
552+
File file = File.createTempFile("blob", ".tmp");
553+
blob.downloadTo(file.toPath());
554+
byte actual[] = Files.readAllBytes(file.toPath());
555+
assertArrayEquals(expected, actual);
556+
}
520557
}

0 commit comments

Comments
 (0)