Most efficient solution for reading CLOB to String, and String to CLOB in Java?

前端 未结 11 1251
长发绾君心
长发绾君心 2020-12-01 07:04

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\" constru

相关标签:
11条回答
  • 2020-12-01 07:47
    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();
    }
    

    The above approach is also very efficient.

    0 讨论(0)
  • 2020-12-01 07:49

    What's wrong with:

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

    ?

    For example Oracle oracle.sql.CLOB performs getSubString() on internal char[] which defined in oracle.jdbc.driver.T4CConnection and just System.arraycopy() and next wrap to String... You never get faster reading than System.arraycopy().

    UPDATE Get driver ojdbc6.jar, and decompile CLOB implementation, and study which case would faster based on internals knowledge.

    0 讨论(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 讨论(0)
  • 2020-12-01 07:55

    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(in);
    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.
    0 讨论(0)
  • 2020-12-01 08:00

    My answer is just a flavor of the same. But I tested it with serializing a zipped content and it worked. So I can trust this solution unlike the one offered first (that use readLine) because it will ignore line breaks and corrupt the input.

    /*********************************************************************************************
     * 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();
    }
    
    0 讨论(0)
  • 2020-12-01 08:00
    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;
    }
    
    0 讨论(0)
提交回复
热议问题