Skip to content

Commit

Permalink
Amazon S3: Add option to download to and overwrite existing files
Browse files Browse the repository at this point in the history
- Issue: aws#2300
  • Loading branch information
mina-asham committed Jul 14, 2021
1 parent 51374cc commit 5d006e7
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 3 deletions.
6 changes: 6 additions & 0 deletions .changes/next-release/feature-AmazonS3-a7371a0.json
@@ -0,0 +1,6 @@
{
"type": "feature",
"category": "Amazon S3",
"contributor": "mina-asham",
"description": "Add option to download to and overwrite existing files"
}
Expand Up @@ -20,10 +20,13 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.file.CopyOption;
import java.nio.file.DirectoryNotEmptyException;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;

import software.amazon.awssdk.annotations.SdkPublicApi;
import software.amazon.awssdk.core.ResponseBytes;
import software.amazon.awssdk.core.ResponseInputStream;
Expand Down Expand Up @@ -93,17 +96,22 @@ default boolean needsConnectionLeftOpen() {

/**
* Creates a response transformer that writes all response content to the specified file. If the file already exists
* then a {@link java.nio.file.FileAlreadyExistsException} will be thrown.
* and overwrite parameter is set to false then a {@link java.nio.file.FileAlreadyExistsException} will be thrown.
*
* @param path Path to file to write to.
* @param overwrite Overwrite existing files.
* @param <ResponseT> Type of unmarshalled response POJO.
* @return ResponseTransformer instance.
*/
static <ResponseT> ResponseTransformer<ResponseT, ResponseT> toFile(Path path) {
static <ResponseT> ResponseTransformer<ResponseT, ResponseT> toFile(Path path, boolean overwrite) {
return (resp, in) -> {
try {
InterruptMonitor.checkInterrupted();
Files.copy(in, path);
if (overwrite) {
Files.copy(in, path, StandardCopyOption.REPLACE_EXISTING);
} else {
Files.copy(in, path);
}
return resp;
} catch (IOException copyException) {
String copyError = "Failed to read response into file: " + path;
Expand Down Expand Up @@ -133,6 +141,18 @@ static <ResponseT> ResponseTransformer<ResponseT, ResponseT> toFile(Path path) {
};
}

/**
* Creates a response transformer that writes all response content to the specified file. If the file already exists
* then a {@link java.nio.file.FileAlreadyExistsException} will be thrown.
*
* @param path Path to file to write to.
* @param <ResponseT> Type of unmarshalled response POJO.
* @return ResponseTransformer instance.
*/
static <ResponseT> ResponseTransformer<ResponseT, ResponseT> toFile(Path path) {
return toFile(path, false);
}

/**
* Creates a response transformer that writes all response content to the specified file. If the file already exists
* then a {@link java.nio.file.FileAlreadyExistsException} will be thrown.
Expand Down
Expand Up @@ -112,6 +112,18 @@ public void downloadToExistingFileDoesNotRetry() throws IOException {
.isInstanceOf(SdkClientException.class);
}

@Test
public void downloadToExistingFileWithOverwriteSucceeds() throws IOException {
stubForSuccess();

Path tmpFile = Files.createTempFile("overwrite-test.", ".tmp");
tmpFile.toFile().deleteOnExit();

testClient().streamingOutputOperation(StreamingOutputOperationRequest.builder().build(), ResponseTransformer.toFile(tmpFile, true));

assertThat(Files.readAllLines(tmpFile)).containsExactly("test \uD83D\uDE02");
}

@Test
public void downloadToOutputStreamDoesNotRetry() throws IOException {
stubForRetriesTimeoutReadingFromStreams();
Expand Down

0 comments on commit 5d006e7

Please sign in to comment.