首页 > 解决方案 > 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();
}

标签: javaxmloracleblob

解决方案


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.


推荐阅读