2010-01-30 6 views
30

मेरे पास एक बड़ा सीएलओबी (32kb से अधिक) है जो मैं स्ट्रिंगबिल्डर का उपयोग करके स्ट्रिंग को पढ़ना चाहता हूं। मैं इसे सबसे कुशल तरीके से कैसे कर सकता हूं? मैं स्ट्रिंगबिल्डर के लिए "int लंबाई" कन्स्ट्रक्टर का उपयोग नहीं कर सकता क्योंकि मेरे सीएलओबी की लंबाई "int" से अधिक है और उसे "लंबा" मान चाहिए।स्ट्रिंग के लिए सीएलओबी पढ़ने के लिए सबसे प्रभावी समाधान, और जावा में सीएलओबी के लिए स्ट्रिंग?

मैं जावा I/O कक्षाओं के साथ confortable नहीं हूँ, और कुछ मार्गदर्शन प्राप्त करना चाहते हैं।

संपादित - मैं clobToString() के लिए इस कोड के साथ की कोशिश की है:

private String clobToString(Clob data) { 
    StringBuilder sb = new StringBuilder(); 
    try { 
     Reader reader = data.getCharacterStream(); 
     BufferedReader br = new BufferedReader(reader); 

     String line; 
     while(null != (line = br.readLine())) { 
      sb.append(line); 
     } 
     br.close(); 
    } catch (SQLException e) { 
     // handle this exception 
    } catch (IOException e) { 
     // handle this exception 
    } 
    return sb.toString(); 
} 
+0

आप एक बार आप एक स्ट्रिंग में CLOB पढ़ा करना चाहते हैं वास्तव में क्या? –

+0

क्या आपका मतलब डेटाबेस ज्ञान में सीएलओबी है, या सिर्फ "बड़ी स्ट्रिंग" है? – skaffman

+0

हां, यह एक डीबी 2 डेटा बेस से एक सीएलओबी है। – Jonas

उत्तर

13

मैं StringBuilder के लिए "पूर्णांक लंबाई" निर्माता उपयोग नहीं कर सकते, क्योंकि मेरी CLOB की लंबाई एक int से अधिक लंबी है और एक long मूल्य की जरूरत है।

यदि सीएलओबी लंबाई int में फ़िट होने से अधिक है, तो सीएलओबी डेटा स्ट्रिंग में फिट नहीं होगा। आपको इस एक्सएमएल डेटा से निपटने के लिए स्ट्रीमिंग दृष्टिकोण का उपयोग करना होगा।

तो CLOB की वास्तविक लंबाई Integer.MAX_VALUE से छोटी है, बस इसे के सामने (int) डालकर int को long बाध्य करते हैं।

+5

वास्तव में, यदि सीएलओबी आकार 2^32 बाइट्स से बड़ा है, तो आपको बड़ी समस्याएं मिली हैं – skaffman

+0

मैं इसे फ़ाइल में लिखने का सुझाव दूंगा, अगर उसे –

34

ठीक है, मैं एक सामान्य उपयोग लगता होगा, सबसे पहले आपको apache commons डाउनलोड करने के लिए है, तो आप एक उपयोगिता वर्ग मिलेगा नाम IOUtils जिसमें कॉपी() नामक एक विधि है;

अब समाधान है: getAsciiStream() का उपयोग करके अपने सीएलओबी ऑब्जेक्ट की इनपुट स्ट्रीम प्राप्त करें और इसे कॉपी() विधि में पास करें।

InputStream in = clobObject.getAsciiStream(); 
StringWriter w = new StringWriter(); 
IOUtils.copy(in, w); 
String clobAsString = w.toString(); 
+0

धन्यवाद, यह अच्छा लग रहा है। लेकिन मैं सवाल थोड़ा और अधिक खोलता हूं, क्योंकि मैं एक समाधान पसंद करूंगा जो केवल मानक पुस्तकालय का उपयोग करता है। – Jonas

+0

मेरे पास पहले से ही अपाचे कॉमन्स लाइब्रेरी लोड है इसलिए यह एकदम सही समाधान है। धन्यवाद! –

+6

getAsciiStream आपको सिरदर्द देगा यदि आप यूनिकोड का उपयोग करते हैं। (या एसीआईआई के बाहर गिरने वाले किसी भी पात्र) –

2

यदि आपको वास्तव में केवल मानक पुस्तकालयों का उपयोग करना होगा, तो आपको केवल उमर के समाधान पर विस्तार करना होगा।

आप पहले से ही तुम बस करने के लिए वर्ण "मैन्युअल रूप से हस्तांतरण" करने के लिए है clobObject.getAsciiStream()

के माध्यम से इनपुट स्ट्रीम प्राप्त करने में सक्षम हैं (अपाचे के IOUtils मूल रूप से बस सुविधा के तरीकों का एक सेट जो कोडिंग का एक बहुत पर बचाता है) StringWriter:

InputStream in = clobObject.getAsciiStream(); 
Reader read = new InputStreamReader(in); 
StringWriter write = new StringWriter(); 

int c = -1; 
while ((c = read.read()) != -1) 
{ 
    write.write(c); 
} 
write.flush(); 
String s = write.toString(); 
मन में

भालू कि

  1. अपने CLOB अधिक चरित्र की तुलना में एक स्ट्रिंग फिट हो, तो यह काम नहीं करेगा।
  2. बेहतर प्रदर्शन के लिए क्रमशः BufferedReader और BufferedWriter के साथ इनपुटस्ट्रीम रीडर और स्ट्रिंगवाइटर लपेटें।
+0

को संसाधित करने के लिए पूरे सीएलओबी की आवश्यकता है जो मेरे द्वारा प्रदान किए गए कोड के समान दिखता है सवाल, क्या उनके बीच कोई महत्वपूर्ण अंतर है जो मैं नहीं देखता हूं? उदाहरण के प्रदर्शन बिंदु में? – Jonas

+0

ओह, मैं आपके कोड खंड पर चूक गया! यह कुछ हद तक समान है, लेकिन ध्यान रखें कि बस BufferedReader.readLine() को पकड़कर, आप लाइनब्रेक्स पर चूक जाएंगे। –

+1

छोटे सुधार लाइन 2 रीडर पढ़ना चाहिए = नया इनपुटस्ट्रीम रीडर (इन); – Vivek

13

मेरा उत्तर सिर्फ इसका एक स्वाद है। लेकिन मैंने इसे एक ज़िप सामग्री को क्रमबद्ध करने के साथ परीक्षण किया और यह काम किया। इसलिए मैं इस समाधान पर भरोसा कर सकता हूं जो पहले पेश किए गए (जैसे रीडलाइन) का उपयोग करता है क्योंकि यह लाइन ब्रेक को अनदेखा कर देगा और इनपुट को दूषित करेगा।

clob.getSubString(1, (int) clob.length()); 

:

/********************************************************************************************* 
* From CLOB to String 
* @return string representation of clob 
*********************************************************************************************/ 
private String clobToString(java.sql.Clob data) 
{ 
    final StringBuilder sb = new StringBuilder(); 

    try 
    { 
     final Reader   reader = data.getCharacterStream(); 
     final BufferedReader br  = new BufferedReader(reader); 

     int b; 
     while(-1 != (b = br.read())) 
     { 
      sb.append((char)b); 
     } 

     br.close(); 
    } 
    catch (SQLException e) 
    { 
     log.error("SQL. Could not convert CLOB to string",e); 
     return e.toString(); 
    } 
    catch (IOException e) 
    { 
     log.error("IO. Could not convert CLOB to string",e); 
     return e.toString(); 
    } 

    return sb.toString(); 
} 
10

क्या बुराई है?

उदाहरण के लिए ओरेकल oracle.sql.CLOBgetSubString() आंतरिक char[] से जो oracle.jdbc.driver.T4CConnection में परिभाषित किया गया है और बस System.arraycopy() और String के बगल में रैप कर ... फिर आप System.arraycopy() तेजी से पढ़ने कभी नहीं मिलता है।

अद्यतन ड्राइवर ojdbc6.jar प्राप्त करें, और CLOB कार्यान्वयन डिकंपाइल, और जो मामले तेजी से आंतरिक ज्ञान के आधार पर होगा अध्ययन करते हैं।

+0

स्ट्रिंग में कई नए अक्षरों को छोड़ देता है। – Gervase

+0

@Gervase न्यूलाइन एक्सएमएल में महत्वपूर्ण हो सकती है। वैसे भी, आप डीबी को संग्रहीत करने से पहले बेकार रिक्त स्थान और न्यूलाइन को ट्रिम करते हैं। –

+0

कुछ बिंदु स्पष्ट करने के लिए: क्या होता है यदि clob.length() Integer.MAX_VALUE से अधिक है? जार में oracle.sql.CLOB क्या है? – Stephan

0
public static String readClob(Clob clob) throws SQLException, IOException { 
    StringBuilder sb = new StringBuilder((int) clob.length()); 
    Reader r = clob.getCharacterStream(); 
    char[] cbuf = new char[2048]; 
    int n; 
    while ((n = r.read(cbuf, 0, cbuf.length)) != -1) { 
     sb.append(cbuf, 0, n); 
    } 
    return sb.toString(); 
} 

उपर्युक्त दृष्टिकोण भी बहुत ही कुशल है।

1
public static final String tryClob2String(final Object value) 
{ 
    final Clob clobValue = (Clob) value; 
    String result = null; 

    try 
    { 
     final long clobLength = clobValue.length(); 

     if (clobLength < Integer.MIN_VALUE || clobLength > Integer.MAX_VALUE) 
     { 
      log.debug("CLOB size too big for String!"); 
     } 
     else 
     { 
      result = clobValue.getSubString(1, (int) clobValue.length()); 
     } 
    } 
    catch (SQLException e) 
    { 
     log.error("tryClob2String ERROR: {}", e); 
    } 
    finally 
    { 
     if (clobValue != null) 
     { 
      try 
      { 
       clobValue.free(); 
      } 
      catch (SQLException e) 
      { 
       log.error("CLOB FREE ERROR: {}", e); 
      } 
     } 
    } 

    return result; 
} 
-1

CLOB, फ़ाइलें की तरह हैं तो आप इस

// read the first 1024 characters 
String str = myClob.getSubString(0, 1024); 

की तरह आसानी से इसे के कुछ हिस्सों को पढ़ सकता है और आप इस

// overwrite first 1024 chars with first 1024 chars in str 
myClob.setString(0, str,0,1024); 

मैं StringBuilder उपयोग करने का सुझाव नहीं है जैसे कि यह करने के लिए अधिलेखित कर सकते हैं और इसे तब तक भरें जब तक कि आप अपवाद नहीं ले लेते, लगभग एक संख्या में प्रवाह को जोड़ने तक लगभग अंधाधुंध जोड़ना पसंद करते हैं। CLOB, एक पाठ फ़ाइल और सबसे अच्छा तरीका यह एक बफर उपयोग कर रहा है पढ़ने के लिए की तरह है मामले में आप, यह प्रक्रिया पूरी की जा अन्यथा आप तो खच्चर का उपयोग कर इस

int s = 0; 
File f = new File("out.txt"); 
FileWriter fw new FileWriter(f); 

while (s < myClob.length()) 
{ 
    fw.write(myClob.getSubString(0, 1024)); 
    s += 1024; 
} 

fw.flush(); 
fw.close(); 
1

की तरह एक स्थानीय फ़ाइल में स्ट्रीम कर सकते हैं नीचे हैं कदम।

नीचे दिए गए चरणों का पालन करें।

कनेक्टर में स्ट्रीमिंग सक्षम यानी progressiveStreaming = 2

Typecast डीबी 2 java.sql.Clob को CLOB लौटे (आईबीएम का समर्थन करता है इस प्रकार के कलाकारों)

चरित्र धारा में रूपांतरित करें कि (ASCII धारा कभी कभी समर्थन नहीं कर सकते कुछ विशेष पात्र)। तो आप getCharacterStream()

का उपयोग कर सकते हैं जो एक "पाठक" ऑब्जेक्ट लौटाएगा जिसे आम-आईओ (IOUtils) का उपयोग करके "स्ट्रिंग" में परिवर्तित किया जा सकता है।

तो संक्षेप में, ग्रोवी घटक का उपयोग करें और कोड नीचे जोड़ें।

clobTest = (java.sql.Clob)payload.field1 
bodyText = clobTest.getCharacterStream() 
targetString = org.apache.commons.io.IOUtils.toString(bodyText) 
payload.PAYLOADHEADERS=targetString return payload 

नोट: यहाँ मैं यह सोचते हैं रहा हूँ "payload.field1" CLOB डेटा पहना हुआ है।

यही है!

सादर नवीन

0
private String convertToString(java.sql.Clob data) 
{ 
    final StringBuilder builder= new StringBuilder(); 

    try 
    { 
     final Reader   reader = data.getCharacterStream(); 
     final BufferedReader br  = new BufferedReader(reader); 

     int b; 
     while(-1 != (b = br.read())) 
     { 
      builder.append((char)b); 
     } 

     br.close(); 
    } 
    catch (SQLException e) 
    { 
     log.error("Within SQLException, Could not convert CLOB to string",e); 
     return e.toString(); 
    } 
    catch (IOException e) 
    { 
     log.error("Within IOException, Could not convert CLOB to string",e); 
     return e.toString(); 
    } 
    //enter code here 
    return builder.toString(); 
} 
+0

आमतौर पर अज्ञात कोड की कुछ पंक्तियों को पोस्ट करने के बजाय समाधान की व्याख्या करना बेहतर होता है। आप पढ़ सकते हैं [मैं एक अच्छा जवाब कैसे लिखूं] (https://stackoverflow.com/help/how-to-answer), और [पूरी तरह से कोड-आधारित उत्तरों समझाएं] (https://meta.stackexchange.com/प्रश्न/114,762/समझा-entirely-% E2% 80% 8C% E2% 80% 8Bcode आधारित-जवाब) –

संबंधित मुद्दे