Ответ 1
Вам нужно закрыть OutputStream
, который очистит оставшуюся часть ваших данных:
out.close();
Размер буфера по умолчанию для BufferedWriter
8192 символов, достаточно большой, чтобы легко хранить сотни строк неписаных данных.
У меня есть программа Java, которая читает текст из файла, строит за строкой и записывает новый текст в выходной файл. Но не весь текст, который я пишу на мой BufferedWriter
, появляется в выходном файле после завершения программы. Почему это?
Подробности: программа принимает текстовый документ CSV и преобразует его в команды SQL, чтобы вставить данные в таблицу. Текстовый файл имеет более 10000 строк, которые выглядят примерно так:
2007,10,9,1,1,1006134,19423882
Программа, кажется, работает отлично, за исключением того, что она просто останавливается в файле случайным образом на полпути, создавая новый оператор SQL, напечатав его в файле SQL. Это выглядит примерно так:
insert into nyccrash values (2007, 1, 2, 1, 4, 1033092, 259916);
insert into nyccrash values (2007, 1, 1, 1, 1, 1020246, 197687);
insert into nyccrash values (2007, 10, 9, 1
Это происходит после примерно 10000 строк, но несколько сотен строк до конца файла. Там, где происходит разрыв, между a 1
и a ,
. Однако символы не кажутся важными, потому что если я изменил значение 1
на a 42
, последнее, что записано в новый файл, - это 4
, который отключает 2 из этого целого. Поэтому кажется, что читатель или писатель должен просто умереть после написания/чтения определенной суммы.
Мой код Java выглядит следующим образом:
import java.io.*;
public class InsertCrashData
{
public static void main (String args[])
{
try
{
//Open the input file.
FileReader istream = new FileReader("nyccrash.txt");
BufferedReader in = new BufferedReader(istream);
//Open the output file.
FileWriter ostream = new FileWriter("nyccrash.sql");
BufferedWriter out = new BufferedWriter(ostream);
String line, sqlstr;
sqlstr = "CREATE TABLE nyccrash (crash_year integer, accident_type integer, collision_type integer, weather_condition integer, light_condition integer, x_coordinate integer, y_coordinate integer);\n\n";
out.write(sqlstr);
while((line = in.readLine())!= null)
{
String[] esa = line.split(",");
sqlstr = "insert into nyccrash values ("+esa[0]+", "+esa[1]+", "+esa[2]+", "+esa[3]+", "+esa[4]+", "+esa[5]+", "+esa[6]+");\n";
out.write(sqlstr);
}
}
catch(Exception e)
{
System.out.println(e);
}
}
}
Вам нужно закрыть OutputStream
, который очистит оставшуюся часть ваших данных:
out.close();
Размер буфера по умолчанию для BufferedWriter
8192 символов, достаточно большой, чтобы легко хранить сотни строк неписаных данных.
Вы должны close()
ваш BufferedWriter
. Вы должны close()
ваш BufferedWriter
потому что он IS-A Writer
и, таким образом, реализует AutoCloseable
, что означает (выделено AutoCloseable
)
Ресурс, который должен быть закрыт, когда он больше не нужен.
Некоторые говорят, что вы должны сначала вызвать flush()
для своего BufferedWriter
прежде чем вызвать close()
. Они не правы. В документации для BufferedWriter.close()
отмечается, что она "закрывает поток, сначала промывая его" (выделено курсором).
Документированная семантика промывки ( flush()
) является
Сбрасывает этот поток, записывая любой буферный вывод в базовый поток
Итак, вы должны close
, и close
будет сброшен любой буферный выход.
Ваш выходной файл не включает весь текст, который вы написали в BufferedWriter
потому что он сохранил часть этого текста в буфере. BufferedWriter
никогда не опустошал этот буфер, передавая его в файл, потому что вы никогда не говорили ему об этом.
Начиная с Java 7, лучший способ обеспечить ресурс AutoCloseable
, такой как BufferedWriter
, закрыт, когда больше не нужно использовать автоматическое управление ресурсами (ARM), также известное как try-with-resources:
try (BufferedWriter out = new BufferedWriter(new FileWriter(file))) {
// writes to out here
} catch (IOException ex) {
// handle ex
}
Вы также должны close
свой BufferedReader
когда он больше не нужен, поэтому у вас должны быть вложенные блоки try-with-resources:
try (BufferedReader in = new BufferedReader(new FileReader("nyccrash.txt")) {
try (BufferedWriter out = new BufferedWriter(new FileWriter("nyccrash.sql"))) {
// your reading and writing code here
}
} catch (IOException ex) {
// handle ex
}
Ресурс, который должен быть закрыт, когда он больше не нужен.
finally {
out.close();//this would resolve the issue
}
Некоторые вещи, которые следует учитывать:
BufferedWriter.close()
удаляет буфер в базовый поток, поэтому, если вы забудете flush()
и не закрываетесь, у вашего файла может не быть всего текста, который вы ему написали.BufferedWriter.close()
также закрывает завернутый Writer. Когда этот FileWriter, это будет в конечном итоге закрыть FileOutputStream и сообщит ОС, что вы закончили запись в файл.close()
, а не BufferedWriter или завернутый FileWriter, но в FileOuputStream. Таким образом, ОС будет счастлива, но вы должны ждать GC.BufferedWriter.close()
очищает внутренний буфер символов, так что память будет доступна для сбора мусора, даже если сам BufferedWriter остается в области видимости.Итак, всегда закрывайте свои ресурсы (а не только файлы), когда вы закончите с ними.
Если вам действительно нужен просмотр под обложками, доступна большая часть источника Java API. BufferedWriter здесь.
Ваш код не закрывает запись после того, как вы закончите писать. Добавьте out.close()
(желательно в блок finally), и он должен работать правильно.
вы закроете свой BufferedWriter.close внутри блока finally
finally {
out.close();//this would resolve the issue
}
вы закроете свой BufferedWriter.close внутри блока finally
finally {
out.close();//this would resolve the issue
}
Это работает. Я столкнулся с той же проблемой, и это сработало для меня. Удачи:)
Всегда закрывайте свои ресурсы (а не только файлы), когда вы закончите с ними.
finally {
out.close();//this would resolve the issue
}
Могут возникнуть ситуации, когда вы хотите сбросить буфер без закрытия файла. В этих ситуациях вы можете использовать метод flush.
Поскольку вы используете BufferedWriter, вы также можете сбросить буфер, если это необходимо:
out.flush()
Это будет записывать остальную часть буфера в фактический файл. Close-метод также очищает буфер и закрывает файл.
out.close()
Могут возникнуть ситуации, когда вы хотите сбросить буфер без закрытия файла. В этих ситуациях вы можете использовать метод flush.
Вы также можете использовать метод newline-метода BuffredWriter вместо добавления \n в конец строки. Newline-method использует системный разделитель строк, поэтому ваш код работает на разных платформах.
out.newLine()