views:

1074

answers:

3

I have a big CLOB (more than 32kB) that I want to read to a String, using StringBuilder. How do I do this in the most efficient way? I can not use the "int length" constructor for StringBuilder since the lenght of my CLOB is longer than a "int" and needs a "long" value.

I am not that confortable with the Java I/O classes, and would like to get some guidance.

Edit - I have tried with this code for 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();
}
A: 

Ok I will suppose a general use, first you have to download apache commons, there you will find an utility class named IOUtils which has a method named copy();

Now the solution is: get the input stream of your CLOB object using getAsciiStream() and pass it to the copy() method.

InputStream in = clobObject.getAsciiStream();
StringWriter w = new StringWriter();
IOUtils.copy(in, w);
String clobAsString = w.toString();
Omar Al Kababji
Thanks, that looks nice. But I leavy the question open little bit more, because I would prefer a solution that only uses the standard library.
Jonas
+1  A: 

I can not use the "int length" constructor for StringBuilder since the length of my CLOB is longer than a int and needs a long value.

If the CLOB length is greater than fits in an int, the CLOB data won't fit in a String either. You'll have to use a streaming approach to deal with this much XML data.

If the actual length of the CLOB is smaller than Integer.MAX_VALUE, just force the long to int by putting (int) in front of it.

Barend
Indeed, if the CLOB size is bigger than 2^32 bytes, you've got big problems
skaffman
A: 

If you really must use only standard libraries, then you just have to expand on Omar's solution a bit. (Apache's IOUtils is basically just a set of convenience methods which saves on a lot of coding)

You are already able to get the input stream through clobObject.getAsciiStream()

You just have to "manually transfer" the characters to the StringWriter:

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

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

Bear in mind that

  1. If your clob contains more character than would fit a string, this won't work.
  2. Wrap the InputStreamReader and StringWriter with BufferedReader and BufferedWriter respectively for better performance.
Edwin Lee
That looks similar to the code i provided in my question, are there any key differences between them that I don't see? In example in a performance point of view?
Jonas
Oops, i missed out on your code fragment! It's somewhat similar, but bear in mind that by just grabbing the BufferedReader.readLine(), you'll miss out on the linebreaks.
Edwin Lee