如何提高BufferedInputStream的转换速度?
小弟对io流很陌生,请问大佬下面的代码怎么优化?图片5Mb的时候要等8sm,怎么提高加载速度?
try {
URL url = new URL(imageUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(5000);
BufferedInputStream bis = new BufferedInputStream(connection.getInputStream());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = bis.read(buffer)) != -1) {
baos.write(buffer, 0, len);
}
OutputStream outputStream = response.getOutputStream();
response.setContentType("image/jpg");
outputStream.write(baos.toByteArray());
outputStream.flush();
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
回复
1个回答

test
2024-08-11
你的问题主要有这么几处:
- 从HTTP读取到的数据,等待全部读取完放在了内存中,等待耗时,文件很大并发时可能会内存溢出
- 阻塞读取,将数据全部存
buffer
过程中,response
一直在等待,什么也没做,可以边读边写 - HTTP请求连接未复用,建议使用
OK-http
等库复用连接 - 资源未释放,
response
会等待超时,且内存会泄露
方案1:原始流复制,这里的buffer
越大,效率越快,但是注意内存占用
HttpURLConnection connection = null;
try {
URL url = new URL(imageUrl);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(5000);
try(InputStream bis = new BufferedInputStream(connection.getInputStream());
OutputStream out = response.getOutputStream()) {
response.setContentType("image/jpg");
// buffer 越大,效率越快
byte[] buffer = new byte[1024];
int len;
while ((len = bis.read(buffer)) != -1) {
out.write(buffer, 0, len);
out.flush();
}
}
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
if(null != connection){
connection.disconnect();
}
}
方案2:使用一些三方库的COPY工具类
HttpURLConnection connection = null;
try {
URL url = new URL(imageUrl);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(5000);
try(InputStream bis = new BufferedInputStream(connection.getInputStream());
OutputStream out = response.getOutputStream()) {
response.setContentType("image/jpg");
IoUtil.copy(bis, out);
}
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
if(null != connection){
connection.disconnect();
}
}
方案3:使用NIO非阻塞传输,同样缓冲区越大,效率越快
HttpURLConnection connection = null;
try {
URL url = new URL(imageUrl);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(5000);
try (ReadableByteChannel in = Channels.newChannel(new BufferedInputStream(connection.getInputStream()));
WritableByteChannel out = Channels.newChannel(response.getOutputStream())) {
response.setContentType("image/jpg");
ByteBuffer byteBuffer = ByteBuffer.allocate(8192);
while (in.read(byteBuffer) != -1) {
// 写转读
byteBuffer.flip();
out.write(byteBuffer);
byteBuffer.clear();
}
}
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
if (null != connection) {
connection.disconnect();
}
}
回复

适合作为回答的
- 经过验证的有效解决办法
- 自己的经验指引,对解决问题有帮助
- 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
- 询问内容细节或回复楼层
- 与题目无关的内容
- “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容