将InputStream转换为byte []的最有效方法?

ChannelBufferInputStream responseStream = (ChannelBufferInputStream) response.getBodyAsStream(); 

ArrayList<Byte> arrayList = new ArrayList<Byte>();

try {

while (responseStream.available() > 0) {

arrayList.add(responseStream.readByte());

}

} catch (IOException e) {

e.printStackTrace();

return internalServerError();

}

Iterator<Byte> iterator = arrayList.iterator();

byte[] bytes = new byte[arrayList.size()];

int i = 0;

while (iterator.hasNext()) {

bytes[i++] = iterator.next();

}

我的网页应用程序的每一页加载都会调用此代码。它似乎运行得非常快,但有什么可以让这个运行速度更快吗?编辑将InputStream转换为byte []的最有效方法?

- 使用字节数组输出流

ChannelBufferInputStream responseStream = (ChannelBufferInputStream) response.getBodyAsStream(); 

ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

try {

int read = responseStream.read();

while (read != -1) {

byteArrayOutputStream.write(read);

read = responseStream.read();

}

} catch (IOException e) {

e.printStackTrace();

return internalServerError();

}

byte[] bytes = byteArrayOutputStream.toByteArray();

return ok(bytes).as(response.getHeader("Content-type"));

编辑更新时间 - 基准测试代码

平均时间后

ChannelBufferInputStream responseStream = (ChannelBufferInputStream) response.getBodyAsStream(); 

long t1 = System.nanoTime();

ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

try {

int read = responseStream.read();

while (read != -1) {

byteArrayOutputStream.write(read);

read = responseStream.read();

}

} catch (IOException e) {

e.printStackTrace();

return internalServerError();

}

byte[] bytes = byteArrayOutputStream.toByteArray();

long t2 = System.nanoTime();

System.out.println(t2-t1);

return ok(bytes).as(response.getHeader("Content-type"));

100+请求 - 46873

平均时间100之后

ChannelBufferInputStream responseStream = (ChannelBufferInputStream) response.getBodyAsStream(); 

long t1 = System.nanoTime();

ArrayList<Byte> arrayList = new ArrayList<Byte>();

try {

while (responseStream.available() > 0) {

arrayList.add(responseStream.readByte());

}

} catch (IOException e) {

e.printStackTrace();

return internalServerError();

}

Iterator<Byte> iterator = arrayList.iterator();

byte[] bytes = new byte[arrayList.size()];

int i = 0;

while (iterator.hasNext()) {

bytes[i++] = iterator.next();

}

long t2 = System.nanoTime();

System.out.println(t2-t1);

return ok(bytes).as(response.getHeader("Content-type"));

+请求 - 522848

平均时间后

long t1 = System.nanoTime(); 

byte[] bytes;

try {

bytes = org.apache.commons.io.IOUtils.toByteArray(responseStream);

} catch (Exception e) {

return internalServerError();

}

long t2 = System.nanoTime();

System.out.println(t2-t1);

100+请求 - 45088的平均时间之后100+请求

long t1 = System.nanoTime(); 

byte[] bytes;

try {

bytes = sun.misc.IOUtils.readFully(responseStream, -1, true);

} catch (Exception e) {

return internalServerError();

}

long t2 = System.nanoTime();

System.out.println(t2 - t1);

- 20180

回答:

是。使用ByteArrayOutputStream而不是ArrayList。然后从InputStream中读取大块字节(不使用available(),几乎总是从不使用),并将这些块写入ByteArrayOutputStream,直到read()方法返回-1。然后在您的ByteArrayOutputStream上调用toByteArray()。

您可以使用Guava的ByteStreams.toByteArray()方法,它可以完成所有这些工作,或者您可以阅读其源代码以更好地了解它是如何工作的。阅读IO tutorial也可能有所帮助。

回答:

为什么?该代码完全等同于read(byte[]),只是它对整个数据执行了两个额外的复制步骤。你不需要这些。一个简单的read(byte[])会快几倍。

使用available()也是无效的。您需要整个响应,而不仅仅是可以无阻塞地读取的部分。你需要循环。

回答:

Apache Commons IO IOUtils.toByteArray方法有什么问题?为此目的已经多年优化。

以上是 将InputStream转换为byte []的最有效方法? 的全部内容, 来源链接: utcz.com/qa/257745.html

回到顶部