Обновите текстовый файл с помощью BufferedWriter

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

FileWriter fw = null;
try {
    fw = new FileWriter("C:/.../" + target + ".pscr",true);
    writer = new BufferedWriter(fw);
    writer.write(target);
    writer.newLine();
    writer.write(Integer.toString(listOfFiles.length));
    writer.newLine();
    for(int i=0; i < listOfFiles.length; i++){
        writer.write(probeArray[i] + "\t" + probeScoreArray[i]);
        writer.newLine();                               
    }                           
}
catch (IOException e1) {e1.printStackTrace();}
catch (RuntimeException r1) {r1.printStackTrace();}
finally {
    try {
        if(writer != null){
            writer.flush();
            writer.close();
        }
    }
    catch (IOException e2) {e2.printStackTrace();}
}

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


person Brandon    schedule 17.02.2010    source источник
comment
Вы не сбрасываете его до тех пор, пока не закроете его, поэтому я не уверен, что вы имеете в виду под предпоследним предложением.   -  person Michael Myers    schedule 18.02.2010
comment
Я читал, что он должен сбрасывать все время, пока он пишет, но файл не создается, так как что-то должно писать.   -  person Brandon    schedule 18.02.2010
comment
Нет, он должен сбрасываться всякий раз, когда заполняется его буфер. Если вы хотите, чтобы он сбрасывался чаще, вы должны сделать это вручную самостоятельно. Но почему тебя это волнует? BufferedWriter используется для повышения эффективности. Если вы этого не хотите, не используйте его. Но в большинстве случаев содержимое файла в основном бесполезно, пока оно не будет заполнено.   -  person user207421    schedule 18.02.2010
comment
Как вы думаете, PrintWriter сделал бы что-нибудь по-другому? Я понимаю, что если мне нужен вывод немедленно по мере его обработки, мне, вероятно, не следует использовать BufferedWriter, но что еще сработает?   -  person Brandon    schedule 18.02.2010
comment
Не могли бы вы обновить свой вопрос, чтобы показать наиболее правильную нерабочую версию кода?   -  person rob    schedule 18.02.2010
comment
@Brandon: Да, PrintWriter с autoflush = true в качестве аргумента конструктора должен работать ... см. мой ответ ниже   -  person Tim    schedule 18.02.2010


Ответы (3)


Вам нужно переместить вызов flush() в блок try. Например, после каждого newLine() вызова.

Тем не менее, flush() в finally является лишним, поскольку close() уже неявно вызывает его.

person BalusC    schedule 17.02.2010
comment
Кажется, я пробовал это раньше, и это не сработало, но я вернул его, чтобы попробовать еще раз, и все тот же результат. - person Brandon; 18.02.2010
comment
Тогда файл, по-видимому, уже открыт/заблокирован чем-то другим внутри той же программы. Что, если вы попытаетесь записать его в другой файл? Например. c:/test.txt или около того. - person BalusC; 18.02.2010
comment
Файл создается только в этот момент времени. Других файлов с таким именем нет. - person Brandon; 18.02.2010
comment
Какая платформа? Какая версия JVM? Не могу воспроизвести это здесь, в WinXP с 1.6.0_17-b04. Я также никогда не видел эту проблему раньше. Разве проблема не в том, как вы тестировали/проверяли, были ли написаны/сброшены строки? - person BalusC; 18.02.2010
comment
работает в eclipse с JVM 1.6.0_17... как еще я могу проверить, было ли оно записано/сброшено, кроме проверки того, был ли создан файл? - person Brandon; 18.02.2010
comment
Да.. Но как вы сейчас это проверяете? F5'ing файл в Eclipse или около того? Лучше протестируйте его, написав в консоль stdout вместо файла, или проверьте, увеличивается ли размер файла в проводнике Windows, или используйте программу для обработки файлов в реальном времени, например TailXP (если вы используете Windows). - person BalusC; 18.02.2010

Просто чтобы быть полностью ясным, здесь вам нужно добавить сброс, если вы хотите сбросить каждую строку, как написано:

for(int i=0; i < listOfFiles.length; i++){
    writer.write(probeArray[i] + "\t" + probeScoreArray[i]);
    writer.newLine();
    writer.flush(); // Make sure the flush() is inside the for loop
}

В вашем коде функция flush() не выполняется до конца программы, потому что блок finally{} не выполняется до тех пор, пока не завершится выполнение блока try{} или catch{}.

person rob    schedule 18.02.2010

Полностью пропустить буферизацию:

Вы печатаете только целые строки как есть, поэтому преимущества, которые он предлагает по сравнению с PrintWriter, теряются в приведенном выше примере из-за вызовов сброса после каждой записи строки.
Как описано здесь: http://java.sun.com/javase/6/docs/api/java/io/BufferedWriter.html

PrintWriter pw = null;
try {
    pw = new PrintWriter(new FileWriter("C:/.../" + target + ".pscr", true), true);
    pw.println(target);
    pw.println(Integer.toString(listOfFiles.length));
    for(int i=0; i < listOfFiles.length; i++)
        pw.println(probeArray[i] + "\t" + probeScoreArray[i]);
}

Последнее обновление:
Вызывается PrintWriter(Writer out, boolean autoFlush), который, согласно Javadoc, имеет следующее поведение:

autoFlush - if true, the println, printf, or format methods will flush the output buffer

Если это не сработает, я не знаю, что будет..

person Tim    schedule 17.02.2010
comment
Я пробовал оба способа и ничего... плюс ни BufferedWriter, ни FileWriter не имеют метода writeln() - person Brandon; 18.02.2010
comment
@Brandon: Извините, у меня не было под рукой IDE. Обновлен мой второй пример для работы с PrintWriter java.sun.com/javase/6/docs/api/java/io/PrintWriter.html, в котором должна быть включена автоматическая очистка, и поэтому она должна работать правильно. Могу я спросить, как вы проверяете правильность сброса файла во время работы программы? - person Tim; 18.02.2010
comment
хорошо, если он сброшен, то файл будет создан при первой обработке чего-либо и продолжит вывод в файл ... но он не создает файл до конца после того, как все было обработано. - person Brandon; 18.02.2010
comment
Я попытался реализовать PrintWriter так же, как и BufferedWriter, и это тоже не сработало... - person Brandon; 18.02.2010
comment
@Brandon: Вы вызвали правильные конструкторы PrintWriter и FileWriter? У обоих должно быть добавлено логическое значение true, первое указывает на то, что вы хотите автоматически очищать каждую строку, второе указывает на включение добавления. Пример кода выше должен работать как есть. - person Tim; 18.02.2010
comment
надо будет проверить...не знаю проверял или нет - person Brandon; 18.02.2010