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