Skip to content

Commit bffab64

Browse files
telendtdagnir
authored andcommitted
Avoid path.toFile calls
1 parent c3891a4 commit bffab64

File tree

5 files changed

+116
-25
lines changed

5 files changed

+116
-25
lines changed

core/src/main/java/software/amazon/awssdk/core/async/FileAsyncRequestBody.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@
1616
package software.amazon.awssdk.core.async;
1717

1818
import java.io.IOException;
19+
import java.io.UncheckedIOException;
1920
import java.nio.ByteBuffer;
2021
import java.nio.channels.AsynchronousFileChannel;
2122
import java.nio.channels.CompletionHandler;
23+
import java.nio.file.Files;
2224
import java.nio.file.Path;
2325
import java.nio.file.StandardOpenOption;
2426
import java.util.concurrent.atomic.AtomicLong;
@@ -57,7 +59,11 @@ private FileAsyncRequestBody(DefaultBuilder builder) {
5759

5860
@Override
5961
public long contentLength() {
60-
return path.toFile().length();
62+
try {
63+
return Files.size(path);
64+
} catch (IOException e) {
65+
throw new UncheckedIOException(e);
66+
}
6167
}
6268

6369
@Override

core/src/main/java/software/amazon/awssdk/core/sync/RequestBody.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,18 @@
1515

1616
package software.amazon.awssdk.core.sync;
1717

18-
import static software.amazon.awssdk.utils.FunctionalUtils.invokeSafely;
1918
import static software.amazon.awssdk.utils.Validate.paramNotNull;
2019
import static software.amazon.awssdk.utils.Validate.validState;
2120

2221
import java.io.ByteArrayInputStream;
2322
import java.io.File;
24-
import java.io.FileInputStream;
23+
import java.io.IOException;
2524
import java.io.InputStream;
25+
import java.io.UncheckedIOException;
2626
import java.nio.ByteBuffer;
2727
import java.nio.charset.Charset;
2828
import java.nio.charset.StandardCharsets;
29+
import java.nio.file.Files;
2930
import java.nio.file.Path;
3031
import java.util.Arrays;
3132
import software.amazon.awssdk.core.runtime.io.ReleasableInputStream;
@@ -81,7 +82,13 @@ public String contentType() {
8182
* @return RequestBody instance.
8283
*/
8384
public static RequestBody fromFile(Path path) {
84-
return fromFile(path.toFile());
85+
try {
86+
return new RequestBody(Files.newInputStream(path),
87+
Files.size(path),
88+
Mimetype.getInstance().getMimetype(path));
89+
} catch (IOException e) {
90+
throw new UncheckedIOException(e);
91+
}
8592
}
8693

8794
/**
@@ -91,9 +98,7 @@ public static RequestBody fromFile(Path path) {
9198
* @return RequestBody instance.
9299
*/
93100
public static RequestBody fromFile(File file) {
94-
return new RequestBody(invokeSafely(() -> new FileInputStream(file)),
95-
file.length(),
96-
Mimetype.getInstance().getMimetype(file));
101+
return fromFile(file.toPath());
97102
}
98103

99104
/**

core/src/main/java/software/amazon/awssdk/core/util/Mimetype.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.io.InputStream;
2222
import java.io.InputStreamReader;
2323
import java.nio.charset.StandardCharsets;
24+
import java.nio.file.Path;
2425
import java.util.HashMap;
2526
import java.util.Map;
2627
import java.util.Optional;
@@ -104,6 +105,24 @@ public static Mimetype getInstance() {
104105
return mimetype;
105106
}
106107

108+
/**
109+
* Determines the mimetype of a file by looking up the file's extension in an internal listing
110+
* to find the corresponding mime type. If the file has no extension, or the extension is not
111+
* available in the listing contained in this class, the default mimetype
112+
* <code>application/octet-stream</code> is returned.
113+
* <p>
114+
* A file extension is one or more characters that occur after the last period (.) in the file's name.
115+
* If a file has no extension,
116+
* Guesses the mimetype of file data based on the file's extension.
117+
*
118+
* @param path the file whose extension may match a known mimetype.
119+
* @return the file's mimetype based on its extension, or a default value of
120+
* <code>application/octet-stream</code> if a mime type value cannot be found.
121+
*/
122+
public String getMimetype(Path path) {
123+
return getMimetype(path.getFileName().toString());
124+
}
125+
107126
/**
108127
* Determines the mimetype of a file by looking up the file's extension in an internal listing
109128
* to find the corresponding mime type. If the file has no extension, or the extension is not
@@ -119,7 +138,7 @@ public static Mimetype getInstance() {
119138
* <code>application/octet-stream</code> if a mime type value cannot be found.
120139
*/
121140
public String getMimetype(File file) {
122-
return getMimetype(file.getName());
141+
return getMimetype(file.toPath());
123142
}
124143

125144
/**

core/src/test/java/software/amazon/awssdk/core/async/AsyncRequestBodyTest.java

Lines changed: 62 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,36 +16,81 @@
1616
package software.amazon.awssdk.core.async;
1717

1818
import static org.assertj.core.api.Assertions.assertThat;
19-
import static org.mockito.Matchers.any;
20-
import static org.mockito.Mockito.spy;
21-
import static org.mockito.Mockito.times;
22-
import static org.mockito.Mockito.verify;
2319

20+
import java.io.IOException;
2421
import java.nio.ByteBuffer;
2522
import java.nio.charset.StandardCharsets;
23+
import java.nio.file.FileSystem;
24+
import java.nio.file.Files;
25+
import java.nio.file.Path;
26+
import java.util.concurrent.CountDownLatch;
27+
import com.google.common.jimfs.Configuration;
28+
import com.google.common.jimfs.Jimfs;
2629
import org.junit.Test;
30+
import org.junit.runner.RunWith;
31+
import org.junit.runners.Parameterized;
2732
import org.reactivestreams.Subscriber;
2833
import software.amazon.awssdk.http.async.SimpleSubscriber;
2934

35+
@RunWith(Parameterized.class)
3036
public class AsyncRequestBodyTest {
37+
private final static String testString = "Hello!";
38+
private final static Path path;
39+
40+
static {
41+
FileSystem fs = Jimfs.newFileSystem(Configuration.unix());
42+
path = fs.getPath("./test");
43+
try {
44+
Files.write(path, testString.getBytes());
45+
} catch (IOException e) {
46+
e.printStackTrace();
47+
}
48+
}
49+
50+
@Parameterized.Parameters
51+
public static AsyncRequestBody[] data() {
52+
return new AsyncRequestBody[]{
53+
AsyncRequestBody.fromString(testString),
54+
AsyncRequestBody.fromFile(path)
55+
};
56+
}
57+
58+
private AsyncRequestBody provider;
59+
60+
public AsyncRequestBodyTest(AsyncRequestBody provider) {
61+
this.provider = provider;
62+
}
63+
64+
@Test
65+
public void hasCorrectLength() {
66+
assertThat(provider.contentLength()).isEqualTo(testString.length());
67+
}
3168

3269
@Test
33-
public void canCreateAStringRequestBody() {
34-
AsyncRequestBody provider = AsyncRequestBody.fromString("Hello!");
70+
public void hasCorrectContent() throws InterruptedException {
3571
StringBuilder sb = new StringBuilder();
36-
boolean done = false;
72+
CountDownLatch done = new CountDownLatch(1);
3773

38-
Subscriber<ByteBuffer> subscriber = spy(new SimpleSubscriber(buffer -> {
39-
byte[] bytes = new byte[buffer.remaining()];
40-
buffer.get(bytes);
41-
sb.append(new String(bytes, StandardCharsets.UTF_8));
42-
}));
74+
Subscriber<ByteBuffer> subscriber = new SimpleSubscriber(buffer -> {
75+
byte[] bytes = new byte[buffer.remaining()];
76+
buffer.get(bytes);
77+
sb.append(new String(bytes, StandardCharsets.UTF_8));
78+
}) {
79+
@Override
80+
public void onError(Throwable t) {
81+
super.onError(t);
82+
done.countDown();
83+
}
4384

44-
provider.subscribe(subscriber);
85+
@Override
86+
public void onComplete() {
87+
super.onComplete();
88+
done.countDown();
89+
}
90+
};
4591

46-
assertThat(sb.toString()).isEqualTo("Hello!");
47-
assertThat(provider.contentLength()).isEqualTo(6);
48-
verify(subscriber).onComplete();
49-
verify(subscriber, times(0)).onError(any(Throwable.class));
92+
provider.subscribe(subscriber);
93+
done.await();
94+
assertThat(sb.toString()).isEqualTo(testString);
5095
}
5196
}

core/src/test/java/software/amazon/awssdk/core/sync/RequestBodyTest.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,14 @@
1717

1818
import static org.assertj.core.api.Assertions.assertThat;
1919

20+
import java.io.IOException;
2021
import java.nio.ByteBuffer;
22+
import java.nio.file.FileSystem;
23+
import java.nio.file.Files;
24+
import java.nio.file.Path;
25+
26+
import com.google.common.jimfs.Configuration;
27+
import com.google.common.jimfs.Jimfs;
2128
import org.junit.Test;
2229
import software.amazon.awssdk.core.util.Mimetype;
2330
import software.amazon.awssdk.core.util.StringInputStream;
@@ -40,6 +47,15 @@ public void stringConstructorHasCorrectContentType() {
4047
assertThat(requestBody.contentType()).isEqualTo(Mimetype.MIMETYPE_TEXT_PLAIN);
4148
}
4249

50+
@Test
51+
public void fileConstructorHasCorrectContentType() throws IOException {
52+
FileSystem fs = Jimfs.newFileSystem(Configuration.unix());
53+
Path path = fs.getPath("./test");
54+
Files.write(path, "hello world".getBytes());
55+
RequestBody requestBody = RequestBody.fromFile(path);
56+
assertThat(requestBody.contentType()).isEqualTo(Mimetype.MIMETYPE_OCTET_STREAM);
57+
}
58+
4359
@Test
4460
public void streamConstructorHasCorrectContentType() {
4561
StringInputStream inputStream = new StringInputStream("hello world");

0 commit comments

Comments
 (0)