2009-05-25 3 views
34

В программе Java (Java 1.5), у меня есть BufferedWriter, что оборачивает в FileWriter, и я называю записи() много много раз ... Получившийся файл является довольно большой ...Когда промывать BufferedWriter

Среди строк этого файла некоторые из них неполные ...

Нужно ли мне называть flush каждый раз, когда я что-то пишу (но я подозреваю, что это будет неэффективно) или использовать другой метод BufferedWriter или использовать другой класс ...?

(Так как у меня есть миллион строк для записи, я хочу иметь что-то довольно эффективное.) Каким будет идеальный момент «промывки»? (Когда я достигаю способность BufferedWriter) ...

Init:

try { 
    analysisOutput = new BufferedWriter(new FileWriter(
     "analysisResults", true)); 
    analysisOutput.newLine(); 
    analysisOutput.write("Processing File " + fileName + "\n"); 
} 
catch (FileNotFoundException ex) { 
    ex.printStackTrace(); 
} 
catch (IOException ex) { 
    ex.printStackTrace(); 
} 

Запись:

private void printAfterInfo(String toBeMoved,HashMap<String, Boolean> afterMap, Location location) 
    throws IOException { 
    if(afterMap != null) { 
     for (Map.Entry<String, Boolean> map : afterMap.entrySet()) { 
     if (toBeMoved == "Condition") { 
      if (1 <= DEBUG) 
      System.out.println("###" + toBeMoved + " " + location + " " 
       + conditionalDefs.get(conditionalDefs.size() - 1) 
       + " After " + map.getKey() + " " 
       + map.getValue() + "\n"); 

      analysisOutput.write("###" + toBeMoved + " " + location + " " 
       + conditionalDefs.get(conditionalDefs.size() - 1) 
       + " After " + map.getKey() + " " + map.getValue() 
       + "\n"); 
     } else { 
      if (1 <= DEBUG) 
      System.out.println("###" + toBeMoved + " " + location + " " 
       + map.getKey() + " After " 
       + map.getValue() + "\n"); 
      if (conditionalDefs.size() > 0) 
      analysisOutput.write("###" + toBeMoved + " " + location + " " 
       + conditionalDefs.get(conditionalDefs.size() - 1) + " " 
       + map.getKey() + " After " + map.getValue() 
       + "\n"); 
      else 
      analysisOutput.write("###" + toBeMoved + " " + location + " " + map.getKey() + " After " + map.getValue() + "\n"); 


     } 
     } 
    } 

Я просто понял, что линии, которые являются неполными являются только перед «Обработка файла» ... так происходит, когда я переключаюсь с одного файла, который я анализирую на другой ...

Закрытие:

dispatch(unit); 

try { 
    if (analysisOutput != null) { 
    printFileInfo(); 
    analysisOutput.close(); 
    } 
} 
catch (IOException ex) { 
    ex.printStackTrace(); 
} 

Иногда информация распечатывается printFileInfo не появляется в файле результатов ...

+0

Если некоторые являются неполными, у вас есть несколько потоков, пишущих на него? IIRC BufferedWriter НЕ является потокобезопасным, поэтому это может быть объяснением, но его НЕ нужно «ругать вручную», чтобы сделать больше места, он сам позаботится об этом. –

+0

Если вы не уверены, что ваш вопрос ясен, возможно, укажите образец кода или образец вывода, который разъясняет. –

+0

На самом деле это поточно-безопасный (хотя у декораторов Writer есть проблемы с соглашением о том, какой объект заблокировать). –

ответ

74

BufferedWriter уже будет промывать, когда заполняет буфер. Из документов по BufferedWriter.write:

Обычно этот метод сохраняет символы из заданного массива в буфер этого ручья, промывки буфера в основной поток по мере необходимости.

(выделено мной.)

Точка BufferedWriter в основном консолидировать много маленьких записей в гораздо меньшем количестве больших записей, как правило, более эффективно (но больше боли код для). Вам не нужно делать что-либо особенное, чтобы заставить его работать исправно, но, кроме того, чтобы убедиться, что вы сбросили его, когда вы закончили , с ним - и вызов close() сделает это, и все равно закроет и закроет создателя.

Другими словами, расслабьтесь - просто пишите, пишите, пишите и закрывайте :) Единственный раз, когда вам обычно нужно звонить flush вручную, действительно вам нужны данные, которые должны быть на диске сейчас. (Например, если у вас есть вечный регистратор, вы можете захотеть очистить его так часто, чтобы каждый, кто читает журналы, не должен ждать, пока буфер не будет заполнен, прежде чем они смогут видеть новые записи в журнале!)

+0

Протестировано и утверждено. Набирается 10 Мб номеров по строкам: промывка после записи каждой строки - занимает 7 секунд, без промывки - 4 секунды. –

8

Идеальный смыва момент, когда вам нужна другая программа читает файл, чтобы увидеть данные, которые были записаны до файла закрыто. Во многих случаях это никогда.

+0

, даже если BufferedWriter большой ... Мне не нужно делать это на промежуточной стадии? – LB40

+0

Если буфер заполняется, он будет записывать его содержимое на диск. BufferedWriter API предназначен для замены в FileWriter, за исключением использования данных перед закрытием файла. – Dave

Смежные вопросы