背景:一次性将几十兆几百兆的文件读到内存里,然后再传给用户,服务器就爆了。
解决原则:读一点传一点。
解决方法:利用流,循环读写。
使用HttpURLConnection和bufferedInputStream 缓存流的方式来获取下载文件,读取InputStream输入流时,每次读取的大小为5M,不一次性读取完,就可避免内存溢出的情况。
/**
* BufferedInputStream 缓存流下载文件
* @param downloadUrl
* @param path
*/
public static void downloadFile(String downloadUrl, String path){
InputStream inputStream = null;
OutputStream outputStream = null;
try {
URL url = new URL(downloadUrl);
//这里没有使用 封装后的ResponseEntity 就是也是因为这里不适合一次性的拿到结果,放不下content,会造成内存溢出
HttpURLConnection connection =(HttpURLConnection) url.openConnection();
//使用bufferedInputStream 缓存流的方式来获取下载文件,不然大文件会出现内存溢出的情况
inputStream = new BufferedInputStream(connection.getInputStream());
File file = new File(path);
if (file.exists()) {
file.delete();
}
outputStream = new FileOutputStream(file);
//这里也很关键每次读取的大小为5M 不一次性读取完
byte[] buffer = new byte[1024 * 1024 * 5];// 5MB
int len = 0;
while ((len = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, len);
}
connection.disconnect();
}catch (Exception e){
e.printStackTrace();
}finally {
IOUtils.closeQuietly(outputStream);
IOUtils.closeQuietly(inputStream);
}
}