Java中读取大文本应使用getCharacterStream()流式处理,避免getString()导致OOM;配合char[]缓冲区循环读写,注意字符编码与资源释放。

Java 中用 JDBC 读取大文本数据,关键不是“一次性取出来”,而是用流式方式边读边处理,避免内存溢出。尤其当数据库字段是 TEXT、CLOB(MySQL/Oracle/PostgreSQL 均支持),不能直接调用 rs.getString()——它会把整段内容加载进内存,GB 级文本极易触发 OOM。
用 getCharacterStream() 流式读取(推荐)
这是最安全、最通用的方式,底层返回 java.io.Reader,可按需分块读取:
- 调用
ResultSet.getCharacterStream("column_name")或getCharacterStream(index) - 配合
char[] buffer = new char[8192]循环read(buffer),每次只处理几 KB - 写入文件、解析 XML、过滤关键词等操作都可在循环中完成,不累积全文本
示例(写入本地文件):
复制代码Reader reader = rs.getCharacterStream("content");<br>FileWriter writer = new FileWriter("output.txt");<br>char[] buf = new char[4096];<br>int len;<br>while ((len = reader.read(buf)) != -1) {<br> writer.write(buf, 0, len);<br>}<br>reader.close();<br>writer.close();
立即学习“Java免费学习笔记(深入)”;
用 getClob() 获取 Clob 对象(适合 Oracle/DB2)
某些数据库驱动对 Clob 提供更精细控制,比如获取子串、定位、流式读取:
Clob clob = rs.getClob("resume");- 再调用
clob.getCharacterStream(),后续逻辑同上 - 若只需前 N 字符,可用
clob.getSubString(1, 1000),避免读全量
注意字符编码与资源释放
数据库字段可能存的是 UTF-8、GBK 或其他编码,而 getCharacterStream() 返回的 Reader 默认使用数据库连接的字符集。若不匹配,会出现乱码:
- 确保 JDBC URL 中指定正确编码,例如 MySQL:
?characterEncoding=utf8mb4 - 不要在 finally 块外关闭 ResultSet ——部分驱动要求 ResultSet 关闭后 Clob/Reader 才真正释放
- 务必显式关闭
Reader和Writer,建议用 try-with-resources
不推荐的做法
以下方式在大文本场景下风险明确,应避免:
-
rs.getString("content"):整字段转 String,堆内存直线上升 -
rs.getObject("content", String.class):本质同 getString - 未设 fetchSize 或未启用流式模式(如 MySQL 需加
&useServerPrepStmts=false&cachePrepStmts=false并调用statement.setFetchSize(Integer.MIN_VALUE))


















