亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何使用 Blob 對象將大型原始 XML 文件寫入 Oracle 數據庫?

如何使用 Blob 對象將大型原始 XML 文件寫入 Oracle 數據庫?

莫回無 2023-03-23 16:42:35
我有一個函數可以使用FileInputStream. 它在我的 IDE 中運行良好,但是當通過可執行文件獨立運行時jar,它拋出Exception in thread "main" java.lang.OutOfMemoryError: Java heap space。我正在讀取字節數組中的這個大文件,以將其作為 Blob 存儲在目標數據庫中。我無法控制 Blob 的存儲方式,我只能訪問存儲過程來插入 Blob。有沒有辦法在不將整個文件加載到內存的情況下讀取和寫入數據塊?將文件轉換為字節數組的函數 -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;}這是使用存儲過程調用將字節數組存儲到 db 的代碼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();}
查看完整描述

2 回答

?
12345678_0001

TA貢獻1802條經驗 獲得超5個贊

使用CallableStatement.setBlob(int, InputStream)或 Blob.setBinaryStream(long)。這兩種方法都可以使用InputStreamorOutputStream對象并避免byte[]在內存中創建數組。示例顯示在將大對象類型對象添加到數據庫文檔中。

只要 JDBC 驅動程序足夠智能,不會byte[]在內部某處為整個 blob 創建,這就應該可以工作。



查看完整回答
反對 回復 2023-03-23
?
白板的微信

TA貢獻1883條經驗 獲得超3個贊

可能是服務器配置過于嚴格?,F在是檢查內存參數的好時機。


只需提供InputStream即可填充 Blob 。


壓縮 XML 數據也是一個好主意。嘗試一下:將一些壓縮test.xml為test.xml.gz,以獲得大小增益。


注意標準java中存在:


private byte[] getBytesFromFile(Path path) throws IOException {

    return Files.readAllBytes(path);

}

所以:


private void storeFileToDb(Connection connection, int fileId, String fileName,

        String fileType) throws SQLException, IOException {

    Path path = Paths.get(fileName); // Or parameter

    try (CallableStatement callableStatement = connection.prepareCall(storedProcedure);

         GZipInputStream fileIn = new GZipInputStream(Files.newBufferedInputStream(path))) {

        ...

        callableStatement.setBlob(4, fileIn);

        ...

    }

}

try-with-resources 確保在拋出異?;蚍祷氐惹闆r下關閉。對語句也很有用。


您沒有關閉語句,里面有一個 Blob。這是不可取的,因為數據可能會停留一段時間。CallableStatement 也是 PreparedStatement,其中一個用例使用可能的其他參數值重復執行 SQL?;虿?。


并用于解壓GZipOutputStream。


查看完整回答
反對 回復 2023-03-23
  • 2 回答
  • 0 關注
  • 161 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號