Skip to content

Commit d4a74c8

Browse files
kilinkbclozel
authored andcommitted
Update StreamUtils drain and emptyInput to use JDK builtins
Update StreamUtils.drain to use InputStream.transferTo with a null OutputStream. This avoids allocating buffers for cases where the supplied InputStream has an optimized transferTo method (e.g., ByteArrayInputStream and FileInputStream). Additionally, update StreamUtils.emptyInput to simply call InputStream.nullInputStream. Closes gh-28961
1 parent 7642ac8 commit d4a74c8

File tree

2 files changed

+9
-13
lines changed

2 files changed

+9
-13
lines changed

spring-core/src/main/java/org/springframework/util/StreamUtils.java

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
package org.springframework.util;
1818

19-
import java.io.ByteArrayInputStream;
2019
import java.io.ByteArrayOutputStream;
2120
import java.io.FilterInputStream;
2221
import java.io.FilterOutputStream;
@@ -62,7 +61,7 @@ public abstract class StreamUtils {
6261
*/
6362
public static byte[] copyToByteArray(@Nullable InputStream in) throws IOException {
6463
if (in == null) {
65-
return new byte[0];
64+
return EMPTY_CONTENT;
6665
}
6766

6867
ByteArrayOutputStream out = new ByteArrayOutputStream(BUFFER_SIZE);
@@ -215,22 +214,15 @@ else if (bytesRead <= bytesToCopy) {
215214
*/
216215
public static int drain(InputStream in) throws IOException {
217216
Assert.notNull(in, "No InputStream specified");
218-
byte[] buffer = new byte[BUFFER_SIZE];
219-
int bytesRead = -1;
220-
int byteCount = 0;
221-
while ((bytesRead = in.read(buffer)) != -1) {
222-
byteCount += bytesRead;
223-
}
224-
return byteCount;
217+
return (int) in.transferTo(OutputStream.nullOutputStream());
225218
}
226-
227219
/**
228220
* Return an efficient empty {@link InputStream}.
229-
* @return a {@link ByteArrayInputStream} based on an empty byte array
221+
* @return an InputStream which contains no bytes
230222
* @since 4.2.2
231223
*/
232224
public static InputStream emptyInput() {
233-
return new ByteArrayInputStream(EMPTY_CONTENT);
225+
return InputStream.nullInputStream();
234226
}
235227

236228
/**

spring-web/src/test/java/org/springframework/http/client/SimpleClientHttpResponseTests.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
import static org.assertj.core.api.Assertions.assertThat;
3030
import static org.mockito.ArgumentMatchers.any;
31+
import static org.mockito.ArgumentMatchers.anyInt;
3132
import static org.mockito.BDDMockito.given;
3233
import static org.mockito.BDDMockito.willDoNothing;
3334
import static org.mockito.Mockito.mock;
@@ -99,7 +100,10 @@ public void shouldNotDrainWhenErrorStreamClosed() throws Exception {
99100
InputStream is = mock(InputStream.class);
100101
given(this.connection.getErrorStream()).willReturn(is);
101102
willDoNothing().given(is).close();
102-
given(is.read(any())).willThrow(new NullPointerException("from HttpURLConnection#ErrorStream"));
103+
given(is.transferTo(any())).willCallRealMethod();
104+
given(is.read(any(), anyInt(), anyInt())).willThrow(new NullPointerException("from HttpURLConnection#ErrorStream"));
105+
106+
is.readAllBytes();
103107

104108
InputStream responseStream = this.response.getBody();
105109
responseStream.close();

0 commit comments

Comments
 (0)