java - How to write large raw XML file to Oracle db using Blob object?
问题描述
I have a function which converts my large XML file to byte array using FileInputStream
. It runs fine within my IDE but on when run independently via the executable jar
, it throws Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
. I'm reading this large file in a byte array to store it as a Blob in the target DB. I don't have control over how the Blob is stored, I just have access to the stored procedure to insert the Blob. Is there a way to read and write chunks of data without loading the entire file in memory ?
function which converts file to byte array -
private byte[] getBytesFromFile(Path path) throws IOException {
FileInputStream fis = new FileInputStream(path.toFile());
byte[] bytes = new byte[(int) path.toFile().length()];
int read = 0;
int offset = 0;
while(offset < bytes.length && (read = fis.read(bytes, offset, bytes.length - offset)) >= 0 ){
offset += read;
}
fis.close();
return bytes;
}
And here's the code which stores the byte array to db using the stored procedure call
private void storeFileToDb(Connection connection, int fileId, String fileName, String fileType, byte[] fileBytes) throws SQLException {
//
String storedProcedure = "{call SP(?,?,?,?,?) }";
CallableStatement callableStatement = connection.prepareCall(storedProcedure);
callableStatement.setInt(1, fileId);
callableStatement.setString(2, fileName);
callableStatement.setString(3, fileType);
Blob fileBlob = connection.createBlob();
fileBlob.setBytes(1, fileBytes);
callableStatement.setBlob(4, fileBlob);
callableStatement.registerOutParameter(5, OracleTypes.NUMBER);
callableStatement.execute();
fileBlob.free(); // not entirely sure how this helps
//callableStatement.close();
}
解决方案
Use either CallableStatement.setBlob(int, InputStream)
or Blob.setBinaryStream(long)
. Both methods will let work with InputStream
or OutputStream
objects and avoid creating byte[]
array in the memory. Example is show in Adding Large Object Type Object to Database docs.
This should work as long as JDBC driver is smart enough not to create byte[]
for the entire blob somewhere internally.
推荐阅读
- asp.net-mvc - (MVC) 使用用户凭据发送电子邮件
- python - 如果颁发者和身份提供者 ID 不同,如何启用 SSO 严格模式?
- c - C y/n 函数无法接受用户输入
- silverstripe - 我可以通过 URL 预填充 Silverstripe 4 中新对象的字段吗?
- r - 如何使用R(arules)中的先验更改规则右侧出现的项目数
- kubernetes - Helm:将 .helm 文件夹提交到源代码管理是否明智?
- flutter - 使用 Flutter-charts 实现折线图。X 轴不重新缩放
- xml - 生成大约 3GB 文件大小的大型 xml 的方法
- linux - 将本地 bash 文件导入另一个 bash 文件
- php - MySql 将 url 从 php 传递到数据库