java - java.lang.OutOfMemoryError: Java 堆空间 Files.readAllBytes(path)
问题描述
我正在将一个大文件(18 GB)转换为一个字节[],但我收到了这个错误:
java.lang.OutOfMemoryError: Java heap space
这是负责异常的代码:
byte[] content = Files.readAllBytes(path);
我正在创建字节数组以通过网络发送它:
createFile(filename.toString(),content);
private ADLStoreClient client; // package com.microsoft.azure.datalake.store
public boolean createFile(String filename, byte[] content) {
try {
// create file and write some content
OutputStream stream = client.createFile(filename, IfExists.OVERWRITE);
// set file permission
client.setPermission(filename, "777");
// append to file
stream.write(content);
stream.close();
} catch (ADLException ex) {
printExceptionDetails(ex);
return false;
} catch (Exception ex) {
log.error(" Exception: {}", ex);
return false;
}
return true;
}
显然 readAllBytes() 将所有字节读入内存并导致 OutOfMemoryError,我认为这可以使用流来解决,但我不擅长它们,任何人都可以给出适当的解决方案,谢谢
解决方案
正如 Azure ADLStoreClient 文档所述:
createFile(String path, IfExists mode)
创建一个文件。如果
overwriteIfExists
为 false 并且文件已经存在,则抛出异常。该调用返回一个ADLFileOutputStream
然后可以写入的。
所以是这样的:
try (InputStream in = new FileInputStream(path);
OutputStream out = client.createFile(filename, IfExists.OVERWRITE)) {
IOUtils.copyLarge(in, out);
}
您可以自己获取IOUtils
或commons-io
制作copyLarge
例程,这非常简单:
void copyLarge(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[65536];
int length;
while ((length = in.read(buffer)) > 0) {
out.write(buffer, 0, length);
}
}
推荐阅读
- html - 仅用于字母字符的输入掩码仅允许 1 个单词在 Angular 中使用 Primeng
- rust - 生锈第二次借用的问题
- node.js - 无法在 Docker、Ubuntu 18.04 上运行 Salesforce trailhead 用户界面 API“安装示例应用程序”
- python - 在 paramiko 的 SSH 会话中更改 $PATH
- c# - 微调器的可见性正在获取状态,但在微调器关闭后微调器的不可见性未按预期工作
- animation - Gnuplot Gif 的问题
- java - Android 构建失败并出现异常
- javascript - 如何导入模块 html 路由器 express js?
- colors - Gnuplot:多图中的颜色不透明
- python - Python到sqlite3:将列表中的元素作为数据库中的新行插入