Java: писать большие файлы?

Приветствую, я получаю огромное количество записей из базы данных и записываю их в файл. Мне было интересно, как лучше всего записывать огромные файлы. (1Гб - 10Гб).

В настоящее время я использую BufferedWriter

BufferedWriter mbrWriter=new BufferedWriter(new FileWriter(memberCSV));
while(done){
 //do writings
}
mbrWriter.close();

person Ashika Umanga Umagiliya    schedule 07.01.2010    source источник
comment
Мне это кажется разумным (кроме выбора случайной кодировки и закрытия основного потока в блоке finally). Вероятно, проблема с производительностью будет зависеть от того, насколько быстро диск может записывать данные (и, вероятно, он захочет снова их прочитать).   -  person Tom Hawtin - tackline    schedule 07.01.2010
comment
(Или параллелизм в этой базе данных. Установите уровень изоляции для соединения. Возможно, установите размер выборки.)   -  person Tom Hawtin - tackline    schedule 07.01.2010


Ответы (3)


Если вы действительно настаиваете на использовании для этого Java, то лучшим способом будет написать немедленно, как только данные поступят, и, таким образом, не собирать все данные из ResultSet в Память Java в первую очередь. В противном случае вам понадобится как минимум столько свободной памяти в Java.

Таким образом, сделайте, например.

while (resultSet.next()) {
    writer.write(resultSet.getString("columnname"));
    // ...
}

Тем не менее, большинство приличных БД поставляются со встроенными возможностями экспорта в CSV, которые, несомненно, намного эффективнее, чем вы когда-либо могли делать в Java. Вы не указали, какой из них вы используете, но если бы это был, например, MySQL, вы могли бы использовать LOAD DATA INFILE для этого. Просто обратитесь к документации по БД. Надеюсь, это даст новые знания.

person BalusC    schedule 07.01.2010

Размер буфера по умолчанию для BufferedWriter равен 8192. Если вы собираетесь записывать файлы с гигабайтами, вы можете увеличить его, используя конструктор с двумя аргументами; например

int buffSize = ... // 1 megabyte or so
BufferedWriter mbrWriter = new BufferedWriter(new FileWriter(memberCSV), buffSize);

Это должно уменьшить количество системных вызовов, необходимых для записи файла.

Но я сомневаюсь, что это даст разницу более чем в пару процентов. Извлечение строк из набора результатов, вероятно, будет основным узким местом производительности. Для значительного повышения производительности вам потребуется использовать собственные средства массового экспорта базы данных.

person Stephen C    schedule 07.01.2010

Я не уверен на 100%, но похоже, что BufferedReader загружает данные в буфер в ОЗУ. Java может использовать 128 МБ оперативной памяти (если не указано иное), поэтому BufferedReader, скорее всего, переполнит память Java, что приведет к ошибке. Попробуйте использовать InputStreamReader и FileInputStream для чтения, а затем сохраните данные в char, а затем просто напишите этот char с помощью FileOutputStream.

person Henry Hammond    schedule 27.03.2010