我需要提供一种下载大文件的方法。
我的实现可行,但可能会在客户端用OutOfMemoryError
失败-有时设置更多的堆帮助,有时却不行。
我在计算机(32GB RAM)上工作得很好,但是在具有〜6GB的计算机上经常失败。
我的文件接近2GB。
应该进行哪些修改以提供故障安全下载方法?
我猜在entity.writeTo(...);
上发生了错误。
我也猜想它会将整个文件存储在内存中,而不应该这样。如何将所有数据写入磁盘并确保没有大的内存缓冲区?
如果我从InputStream
的{{1}}块中读取内容会有所帮助吗?
同一问题适用于服务器。我之所以使用byte[1024]
来传输数据,是因为我在某处读取了它调用OS的API函数的信息,并且实际发生了磁盘I / O。
客户:
Files.copy(...)
服务器:
public boolean requestUpdateDownload(String filePath)
{
Path path = Paths.get(filePath).toAbsolutePath();
File file = path.toFile();
String url = "http://" + host + ":" + port + "/download";
System.out.println("Downloading update file from " + url);
try
{
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet(url);
CloseableHttpResponse response = httpClient.execute(httpGet);
try
{
System.out.println(response.getStatusLine());
HttpEntity entity = response.getEntity();
long expectedSize = entity.getContentLength();
if (entity != null)
{
try (FileOutputStream fileOutputStream = new FileOutputStream(file))
{
entity.writeTo(fileOutputStream);
}
}
EntityUtils.consume(entity);
long realSize = file.length();
if (expectedSize == realSize)
{
System.out.println("Received update file: " + realSize + " bytes total.");
}
else
{
System.err.println("Update file incomplete.");
deleteFile(path);
}
}
finally
{
response.close();
}
System.out.println("Saving update file to \"" + path + "\"");
System.out.println("Update file saved.");
}
catch (Exception ex)
{
System.err.println("Unable to download update file.");
ex.printStackTrace();
deleteFile(path);
return false;
}
return true;
}