parse convert java stringbuilder clob

java - parse - convert clob to string



¿La solución más eficiente para leer CLOB en String, y String to CLOB en Java? (11)

Tengo un gran CLOB (más de 32kB) que quiero leer en una cadena, usando StringBuilder. ¿Cómo hago esto de la manera más eficiente? No puedo usar el constructor "int length" para StringBuilder ya que la duración de mi CLOB es más larga que "int" y necesita un valor "largo".

No soy tan cómodo con las clases de E / S de Java y me gustaría obtener orientación.

Editar - He intentado con este código para 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(); }


No puedo usar el constructor "longitud int" para StringBuilder ya que la longitud de mi CLOB es más larga que un int y necesita un valor long .

Si la longitud de CLOB es mayor que la que cabe en una int, los datos de CLOB tampoco caben en una cadena. Tendrá que usar un enfoque de transmisión para tratar con esta cantidad de datos XML.

Si la longitud real del CLOB es menor que Integer.MAX_VALUE , simplemente fuerce el long a int colocando (int) delante de él.


CLOB son como archivos, puedes leer partes fácilmente como este

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

y puedes sobreescribirlo así

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

No sugiero usar StringBuilder y llenarlo hasta que obtenga una excepción, casi como agregar números ciegamente hasta que obtenga un desbordamiento. Clob es como un archivo de texto y la mejor manera de leerlo es usar un búfer, en caso de que necesite procesarlo, de lo contrario, puede transmitirlo a un archivo local como este

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


Mi respuesta es solo un sabor de lo mismo. Pero lo probé con la serialización de un contenido comprimido y funcionó. Así que puedo confiar en esta solución a diferencia de la que se ofrece primero (que usa readLine) porque ignorará los saltos de línea y dañará la entrada.

/********************************************************************************************* * 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(); }


Ok, supongo que se trata de un uso general, primero tienes que descargar apache commons , allí encontrarás una clase de utilidad llamada IOUtils que tiene un método llamado copy ();

Ahora la solución es: obtener el flujo de entrada de su objeto CLOB usando getAsciiStream () y pasarlo al método copy ().

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


Qué hay de malo en:

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

?

Por ejemplo, Oracle oracle.sql.CLOB make getSubString() de la char[] interna char[] que se definió en oracle.jdbc.driver.T4CConnection y simplemente System.arraycopy() y la siguiente envolvente en String ... Nunca se obtiene una lectura más rápida que System.arraycopy() .

ACTUALIZACIÓN Obtenga el controlador ojdbc6.jar y descompile la implementación de CLOB , y estudie qué caso sería más rápido según el conocimiento interno.


Si realmente debes usar solo bibliotecas estándar, entonces solo tienes que expandir un poco la solución de Omar. (IOUtils de Apache es básicamente un conjunto de métodos de conveniencia que ahorra mucha codificación)

Ya puede obtener la corriente de entrada a través de clobObject.getAsciiStream()

Solo tiene que "transferir manualmente" los caracteres al 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();

Tener en cuenta que

  1. Si tu clob contiene más caracteres de los que cabría una cadena, esto no funcionará.
  2. Envuelva el InputStreamReader y StringWriter con BufferedReader y BufferedWriter respectivamente para un mejor rendimiento.

Si usa Mule, a continuación se muestran los pasos.

Sigue los pasos a continuación.

Habilite la transmisión en el conector, es decir, progressiveStreaming = 2

Typecast DB2 devolvió CLOB a java.sql.Clob (IBM admite este tipo de conversión)

Convierta eso en una secuencia de caracteres (la transmisión ASCII a veces puede no ser compatible con algunos caracteres especiales). Entonces puede usar getCharacterStream ()

Eso devolverá un objeto "lector" que se puede convertir a "Cadena" utilizando common-io (IOUtils).

En resumen, use el componente groovy y agregue el código siguiente.

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

Nota: Aquí estoy suponiendo que "payload.field1" está conteniendo datos clob.

¡Eso es!

Saludos Naveen


Un método de ayuda amigable que utiliza apache commons.io

Reader reader = clob.getCharacterStream(); StringWriter writer = new StringWriter(); IOUtils.copy(reader, writer); String clobContent = writer.toString();


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


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

El enfoque anterior también es muy eficiente.


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; }