Вам не нужен временный файл. Байт-буфер, который вы создаете там в зависимости от размера файла, также может вызвать OutOfMemoryError
. Это все просто неэффективно.
Просто запишите данные ResultSet
немедленно в ответ HTTP, итерируя по строкам. В основном: writer.write(resultSet.getString("columnname"))
. Таким образом, вам не нужно записывать его во временный файл или сожрать все в памяти Java.
Кроме того, большинство драйверов JDBC по умолчанию кэшируют все в памяти Java, прежде чем что-либо выдать ResultSet#next()
. Это тоже неэффективно. Вы бы хотели, чтобы он давал данные сразу построчно, устанавливая Statement#setFetchSize()
. Как это сделать правильно, зависит от используемого драйвера JDBC. В случае, например, MySQL, вы можете прочитать его в документации драйвера JDBC .
Вот начальный пример, предполагающий, что вы используете MySQL:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/csv");
response.setCharacterEncoding("UTF-8");
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
PrintWriter writer = response.getWriter();
try {
connection = database.getConnection();
statement = connection.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
statement.setFetchSize(Integer.MIN_VALUE);
resultSet = statement.executeQuery("SELECT col1, col2, col3 FROM tbl");
while (resultSet.next()) {
writer.append(resultSet.getString("col1")).append(',');
writer.append(resultSet.getString("col2")).append(',');
writer.append(resultSet.getString("col3")).println();
// Note: don't forget to escape quotes/commas as per RFC4130.
}
} catch (SQLException e) {
throw new ServletException("Retrieving CSV rows from DB failed", e);
} finally {
if (resultSet != null) try { resultSet.close; } catch (SQLException logOrIgnore) {}
if (statement != null) try { statement.close; } catch (SQLException logOrIgnore) {}
if (connection != null) try { connection.close; } catch (SQLException logOrIgnore) {}
}
}
Вот и все. Таким образом, только одна строка базы данных постоянно сохраняется в памяти.