Browse Source

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
pull/29136/head
Patrick Strawderman 4 years ago committed by Brian Clozel
parent
commit
d4a74c8f9d
  1. 16
      spring-core/src/main/java/org/springframework/util/StreamUtils.java
  2. 6
      spring-web/src/test/java/org/springframework/http/client/SimpleClientHttpResponseTests.java

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

@ -16,7 +16,6 @@ @@ -16,7 +16,6 @@
package org.springframework.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FilterInputStream;
import java.io.FilterOutputStream;
@ -62,7 +61,7 @@ public abstract class StreamUtils { @@ -62,7 +61,7 @@ public abstract class StreamUtils {
*/
public static byte[] copyToByteArray(@Nullable InputStream in) throws IOException {
if (in == null) {
return new byte[0];
return EMPTY_CONTENT;
}
ByteArrayOutputStream out = new ByteArrayOutputStream(BUFFER_SIZE);
@ -215,22 +214,15 @@ public abstract class StreamUtils { @@ -215,22 +214,15 @@ public abstract class StreamUtils {
*/
public static int drain(InputStream in) throws IOException {
Assert.notNull(in, "No InputStream specified");
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead = -1;
int byteCount = 0;
while ((bytesRead = in.read(buffer)) != -1) {
byteCount += bytesRead;
}
return byteCount;
return (int) in.transferTo(OutputStream.nullOutputStream());
}
/**
* Return an efficient empty {@link InputStream}.
* @return a {@link ByteArrayInputStream} based on an empty byte array
* @return an InputStream which contains no bytes
* @since 4.2.2
*/
public static InputStream emptyInput() {
return new ByteArrayInputStream(EMPTY_CONTENT);
return InputStream.nullInputStream();
}
/**

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

@ -28,6 +28,7 @@ import org.springframework.util.StreamUtils; @@ -28,6 +28,7 @@ import org.springframework.util.StreamUtils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.willDoNothing;
import static org.mockito.Mockito.mock;
@ -99,7 +100,10 @@ public class SimpleClientHttpResponseTests { @@ -99,7 +100,10 @@ public class SimpleClientHttpResponseTests {
InputStream is = mock(InputStream.class);
given(this.connection.getErrorStream()).willReturn(is);
willDoNothing().given(is).close();
given(is.read(any())).willThrow(new NullPointerException("from HttpURLConnection#ErrorStream"));
given(is.transferTo(any())).willCallRealMethod();
given(is.read(any(), anyInt(), anyInt())).willThrow(new NullPointerException("from HttpURLConnection#ErrorStream"));
is.readAllBytes();
InputStream responseStream = this.response.getBody();
responseStream.close();

Loading…
Cancel
Save