2017-07-20 112 views
0

我们正在进行大量的xml处理,并将clob转换为字符串的逻辑如下所示。如何将clob转换为java中的编码字符串

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)似乎工作正常可能是我使用显式重写的系统编码?

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

c。我想过不使用Apache公共库,并使用简单的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() 
}  

你们可以请一些光来理解它们。

回答

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

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

+0

谢谢..我更了解何时使用编码,并且当您已经处理字符流时不需要将它们转换为字节。第二个例子是我使用java标准库的好例子吗? – user292049

+0

是的,它看起来不错。这样做可能有更“现代”的方式,但在这样的循环中读入“StringBuffer”没有任何问题。 – Kayaman

相关问题