2017-07-20 116 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

相關問題