我们正在进行大量的 xml 处理,将 clob 转换为字符串的逻辑如下所示。
import java.sql.Clob
import org.apache.commons.io.IOUtils
String extractXml(Clob xmlClob) {
log.info "DefaultCharset: " + groovy.util.CharsetToolkit.getDefaultSystemCharset()
String sourceXml
try {
sourceXml = new String(IOUtils.toByteArray(xmlClob?.getCharacterStream()), encoding) // 1. Encoding not working
sourceXml = new String(IOUtils.toByteArray(xmlClob?.getCharacterStream(), encoding), encoding) // 2. Encoding working
} catch (Exception e) {
...
}
return sourceXml
}
我的查询:
a.我不确定为什么 (1) 不起作用,即使我使用 getCharacterStream() 而不是 getAsciiStream()。 但是(2)似乎工作正常,可能是我正在使用系统编码的显式覆盖?
b.解决方案 (2) 看起来有点奇怪,因为您指定了 2 倍的编码格式(一次用于字节数组,一次用于字符串创建)。 我不确定是否存在任何性能问题或想知道是否有更好的方法来编写它们?
c.我想到不使用 Apache-commons 库并使用简单的 java 包解决方案。 但令人惊讶的是,我没有给出任何显式编码,但它似乎工作得很好。 是因为它确实“流字符 -> 直接到字符串缓冲”吗?
/*
* working perfectly and retuns encoding correctly
*/
String extractXmlWithoutApacheCommons(Clob xmlClob) {
log.info "DefaultCharset: " + groovy.util.CharsetToolkit.getDefaultSystemCharset()
StringBuffer sb = new StringBuffer((int) xmlClob.length())
try {
Reader r = xmlClob.getCharacterStream()
char[] cbuf = new char[2048]
int n = 0
while ((n = r.read(cbuf, 0, cbuf.length)) != -1) {
if (n > 0) {
sb.append(cbuf, 0, n)
}
}
} catch (Exception e) {
...
}
return sb.toString()
}
请你们提供一些线索来理解它们。
最佳答案
Clob
已经有一个编码。它是您在数据库中指定的任何内容,一旦您在 Java 端读取它,它将是一个 String
(使用隐式 UTF-16 编码,这根本不重要)。
无论你认为你用所有这些编码技巧做什么都是错误且无用的。您只需在将 bytes
转换为 chars
或反之时指定编码。您仅处理 chars
(除了在第一个示例中,您出于某种未知原因想要将它们转换为字节)。
如果您想使用 IOUtils
,则可以使用 readFully(Reader input, char[] buffer)
方法。
平台默认编码对整个问题没有影响,因为您根本不应该使用字节。
编辑:
使用标准 JDK 类的稍微更现代的方法是使用 Reader.read(CharBuffer target)
,例如
CharBuffer cb = CharBuffer.allocate((int) xmlClob.length());
while(r.read(cb) != -1)
;
return cb.toString();
但它并没有真正产生很大的区别(它看起来更好一点)。
关于java - java中如何使用编码将clob转换为字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45216772/