Когда очищать BufferedWriter - PullRequest
41 голосов
/ 26 мая 2009

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

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

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

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

Инициатива:

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, не появляется в файле результатов ...

Ответы [ 3 ]

84 голосов
/ 26 мая 2009

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

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

(Акцент мой.)

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

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

11 голосов
/ 26 мая 2009

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

0 голосов
/ 11 октября 2018

Если у вас есть цикл, чередующийся init и printAfterInfo, я полагаю, что ваша проблема заключается в том, что вы не close пишете, прежде чем создавать новый для того же файла. Вам лучше создать BufferedWriter один раз и закрыть его в конце всей обработки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...