提交 ae3dda4e 编写于 作者: A andrew

8193832: Performance of InputStream.readAllBytes() could be improved

Summary: Read into a list of fixed-size buffers which are gathered at the end
Reviewed-by: mbalao
上级 b6dd6ba8
...@@ -33,7 +33,9 @@ import java.io.EOFException; ...@@ -33,7 +33,9 @@ import java.io.EOFException;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List;
import java.util.Objects; import java.util.Objects;
public class IOUtils { public class IOUtils {
...@@ -140,30 +142,55 @@ public class IOUtils { ...@@ -140,30 +142,55 @@ public class IOUtils {
* @since 1.9 * @since 1.9
*/ */
public static byte[] readAllBytes(InputStream is) throws IOException { public static byte[] readAllBytes(InputStream is) throws IOException {
List<byte[]> bufs = null;
byte[] result = null;
int total = 0;
int n;
do {
byte[] buf = new byte[DEFAULT_BUFFER_SIZE]; byte[] buf = new byte[DEFAULT_BUFFER_SIZE];
int capacity = buf.length;
int nread = 0; int nread = 0;
int n;
for (;;) {
// read to EOF which may read more or less than initial buffer size
while ((n = is.read(buf, nread, capacity - nread)) > 0)
nread += n;
// if the last call to read returned -1, then we're done // read to EOF which may read more or less than buffer size
if (n < 0) while ((n = is.read(buf, nread, buf.length - nread)) > 0) {
break; nread += n;
}
// need to allocate a larger buffer if (nread > 0) {
if (capacity <= MAX_BUFFER_SIZE - capacity) { if (MAX_BUFFER_SIZE - total < nread) {
capacity = capacity << 1;
} else {
if (capacity == MAX_BUFFER_SIZE)
throw new OutOfMemoryError("Required array size too large"); throw new OutOfMemoryError("Required array size too large");
capacity = MAX_BUFFER_SIZE;
} }
buf = Arrays.copyOf(buf, capacity); total += nread;
if (result == null) {
result = buf;
} else {
if (bufs == null) {
bufs = new ArrayList<>();
bufs.add(result);
}
bufs.add(buf);
}
}
} while (n >= 0); // if the last call to read returned -1, then break
if (bufs == null) {
if (result == null) {
return new byte[0];
}
return result.length == total ?
result : Arrays.copyOf(result, total);
}
result = new byte[total];
int offset = 0;
int remaining = total;
for (byte[] b : bufs) {
int len = Math.min(b.length, remaining);
System.arraycopy(b, 0, result, offset, len);
offset += len;
remaining -= len;
} }
return (capacity == nread) ? buf : Arrays.copyOf(buf, nread);
return result;
} }
/** /**
......
...@@ -34,7 +34,7 @@ import sun.misc.IOUtils; ...@@ -34,7 +34,7 @@ import sun.misc.IOUtils;
/* /*
* @test * @test
* @bug 8080835 * @bug 8080835 8193832
* @library /lib/testlibrary * @library /lib/testlibrary
* @build jdk.testlibrary.* * @build jdk.testlibrary.*
* @run main ReadAllBytes * @run main ReadAllBytes
...@@ -50,15 +50,11 @@ public class ReadAllBytes { ...@@ -50,15 +50,11 @@ public class ReadAllBytes {
test(new byte[]{}); test(new byte[]{});
test(new byte[]{1, 2, 3}); test(new byte[]{1, 2, 3});
test(createRandomBytes(1024)); test(createRandomBytes(1024));
test(createRandomBytes((1 << 13) - 1)); for (int shift : new int[] {13, 14, 15, 17}) {
test(createRandomBytes((1 << 13))); for (int offset : new int[] {-1, 0, 1}) {
test(createRandomBytes((1 << 13) + 1)); test(createRandomBytes((1 << shift) + offset));
test(createRandomBytes((1 << 15) - 1)); }
test(createRandomBytes((1 << 15))); }
test(createRandomBytes((1 << 15) + 1));
test(createRandomBytes((1 << 17) - 1));
test(createRandomBytes((1 << 17)));
test(createRandomBytes((1 << 17) + 1));
} }
static void test(byte[] expectedBytes) throws IOException { static void test(byte[] expectedBytes) throws IOException {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册