如何在java

时间:2017-07-20 13:52:58

标签: java unicode apache-commons-io

我们正在进行大量的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
}

我的疑问:

一个。我不确定为什么(1)即使我使用getCharacterStream()而不是getAsciiStream()也不起作用。     但(2)似乎工作正常可能是我使用显式覆盖系统编码?

湾解决方案(2)看起来很奇怪,因为你指定了2倍的编码格式(一个用于字节数组,一个用于字符串创建)。    我不确定是否有任何性能问题,或者想知道是否有更好的方法来编写它们?

℃。我想过不使用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()
}    

你们能不能理解它们。

1 个答案:

答案 0 :(得分:2)

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();

但它并没有真正产生巨大的变化(看起来好一点)。