Чтение и запись больших файлов CLOB из базы данных быстрее

У меня есть задача прочитать файлы CLOB из базы данных Oracle 9i и записать их в файлы. То, что у меня есть, работает для небольших файлов, но в случае больших файлов, около 200 МБ, для одного файла требуется около 5 часов, что совершенно неприемлемо. Я уверен, что это можно сделать быстрее, но я не уверен, как это сделать. Вот что у меня есть:

//get the Clob record from the database and convert it to String
 public String getClobRecord() {
        Connection conn;
        Clob xmlCont;
        ResultSet rset;
        PreparedStatement stmt;
        try {
            conn = db.prepareConn();
            String sql = "select a.clob_clm from xml_statement a where period_id = ?";
            stmt = conn.prepareStatement(sql);
            stmt.setInt(1, pid);
            rset = stmt.executeQuery();
            while (rset.next()) {
                xmlCont = rset.getClob(1);
                xml = ClobStringConversion(xmlCont);
            }

            stmt.close();
            DBConnect.closeConn(conn);
        } catch (SQLException asd) {
            log.fatal(asd.getMessage());
        } catch (IOException asd) {
            log.fatal(asd.getMessage());
        }
        return xml;
    }
//My CLOB to String Conversion Method
  public static String ClobStringConversion(Clob clb) throws SQLException, IOException {
        if (clb == null) {
            return "";
        }
        StringBuilder str = new StringBuilder();
        String strng;
        BufferedReader br = new BufferedReader(clb.getCharacterStream());
        while ((strng = br.readLine()) != null) {
            str.append(strng);
        }

        return str.toString();
    }
//Write the String to File
public void writeXmlToFile(String fileDir, String xmlFileName) {
        File xmlfile = new File(fileDir + "/" + xmlFileName);
        xml = this.getClobRecord();
        try {
            BufferedWriter bw = new BufferedWriter(new FileWriter(xmlfile));
            bw.write(formatXmlFile());
            bw.close();
        } catch (IOException asd) {
            log.fatal(asd.getMessage());
        }
    }

Что именно я должен изменить, чтобы разместить очень большие файлы CLOB?


person ErrorNotFoundException    schedule 27.03.2015    source источник
comment
Я удивлен, что вы ждали 5 часов, пока закончится тест.   -  person user253751    schedule 27.03.2015
comment
Не совсем :) Оставил его включенным на ночь.. Проверил журналы позже.. Это заняло много времени.   -  person ErrorNotFoundException    schedule 27.03.2015
comment
Какой длины строки в данных?   -  person user253751    schedule 27.03.2015
comment
Не очень длинный, на самом деле он в формате XML. Уменьшенный образец файла выглядит так, как на скриншоте, который я прикрепляю.   -  person ErrorNotFoundException    schedule 27.03.2015
comment
Примечание: единственный способ узнать, действительно ли ответ работает, - это использовать ответ, а затем снова запустить его на ночь и посмотреть, станет ли он быстрее.   -  person user253751    schedule 27.03.2015
comment
Как вы подошли к этой проблеме?   -  person happybuddha    schedule 21.11.2018


Ответы (1)


Если вы настаиваете на хранении данных clob в памяти, вы можете улучшить одну вещь — использовать функцию, специфичную для оракула.

public static String toString(final Clob clob)
    throws SQLException, IOException {

    if (clob == null) {
        return "";
    }

    Long length = null;

    // try to get the oracle specific CLOB length
    // no vendor-specific code here.
    try {
        final Class<?> oracleClobClass = Class.forName("oracle.sql.CLOB");
        if (oracleClobClass.isInstance(clob)) {
            length = (Long) oracleClobClass.getMethod("getLength", null)
                     .invoke(clob, null);
        }
    } catch (final Exception e) {
    }

    // we can set initial capacity if we got the length.
    final StringBuilder builder
        = length == null
        ? new StringBuilder() : new StringBuilder(length.intValue());

    final BufferedReader reader
        = new BufferedReader(clob.getCharacterStream());
    for (String line = null; (line = reader.readLine()) != null; ) {
        builder.append(line);
    }

    return builder.toString();
}
person Jin Kwon    schedule 27.03.2015