Подтвердить что ты не робот

BufferedWriter не записывает все в свой выходной файл

У меня есть программа 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);
        }
    }
}
4b9b3361

Ответ 1

Вам нужно закрыть OutputStream, который очистит оставшуюся часть ваших данных:

out.close();

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

Ответ 2

Вы должны 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
 }

Ответ 3

Ресурс, который должен быть закрыт, когда он больше не нужен.

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 здесь.

Ответ 4

Ваш код не закрывает запись после того, как вы закончите писать. Добавьте out.close() (желательно в блок finally), и он должен работать правильно.

Ответ 5

вы закроете свой BufferedWriter.close внутри блока finally

   finally {
    out.close();//this would resolve the issue
    }

Ответ 6

вы закроете свой BufferedWriter.close внутри блока finally

finally {
out.close();//this would resolve the issue
}

Это работает. Я столкнулся с той же проблемой, и это сработало для меня. Удачи:)

Ответ 7

Всегда закрывайте свои ресурсы (а не только файлы), когда вы закончите с ними.

 finally {
    out.close();//this would resolve the issue
    }

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

Ответ 8

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

out.flush()

Это будет записывать остальную часть буфера в фактический файл. Close-метод также очищает буфер и закрывает файл.

out.close()

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

Вы также можете использовать метод newline-метода BuffredWriter вместо добавления \n в конец строки. Newline-method использует системный разделитель строк, поэтому ваш код работает на разных платформах.

out.newLine()