Почему BufferedWriter частично записывает данные в файл?

Я пытаюсь написать JSON-файл, используя этот код:

        File f = new File("words_3.json");
        if (!f.exists()) {
            f.createNewFile();
        }
        if (fileWriter == null)
            fileWriter = new BufferedWriter(new FileWriter(f));
        while (scanner.hasNext()) {
            String text = scanner.nextLine(); 
                    fileWriter.append(text);
                    System.out.println("writing : "+text);
        }

Оператор System.out.println() показывает весь текст в терминале.

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

Для меня это звучит так, как будто вы неправильно закрываете BufferedWriter. Можете ли вы показать, как вы открываете и закрываете его?

Thomas Kläger 23.03.2022 06:13

Я не закрывал bufferedWritter как записывающее значение записи во время выполнения цикла. позвольте мне проверить это

eFortsHub 23.03.2022 06:17

2thanks, когда я закрою BufferedWriter . он записывает весь текст в файл

eFortsHub 23.03.2022 06:20

Если решение, представленное в моем ответе, не решает вашу проблему или что-то неясно, оставьте комментарий.

Alexander Ivanchenko 23.03.2022 19:13

Оно работает. мне удалить этот вопрос или оставить как есть? В любом случае, большое спасибо за улучшение вопроса

eFortsHub 24.03.2022 14:10

@eFortsHub Поскольку вопрос решен, он представляет собой пара проблема-решение и его стоит сохранить для будущих читателей. Итак, определенно Оставь это.

Alexander Ivanchenko 24.03.2022 18:06
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
6
64
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

BufferedWritter — это так называемый поток высокого уровня, который украшает базовый поток, который имеет дело с конкретным пунктом назначения данных, например FileWriter (и между ними может быть еще несколько потоков), путем буферизации вывода текста и предоставления метода убеждения newLine().

BufferedWritter поддерживает буфер (массив символов) с размером по умолчанию 8192. И когда это наполняется, он передает его базовому низкоуровневый поток. В данном случае к FileWriter, который позаботится о кодировании персонажи в байты.

Когда это будет сделано, JVM передаст данные Операционная система через FileOutputStream (потому что под капотом потоки символов строятся поверх потоков укусов).

Итак, данные, записанные в буфер, появятся в файл в куски:

  • когда буфернаполняется;
  • и после поток был закрыто.

Javadoc для метода close() говорит:

Closes the stream, flushing it first.

т.е. перед освобождением ресурса close() вызывает метод flush(), который принудительно передает кэшированные данные по назначению.

Если исключения не возникнет, все, что было записано в поток, гарантированно достигнет места назначения при закрытии потока.

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

«JVM передает их операционной системе, которая будет хранить эти данные в кеше». это неверно, буферизованный писатель имеет буфер внутри Java.
Mark Rotteveel 23.03.2022 17:50

@MarkRotteveel Я знаю это. Итак, когда BufferedWriter передаст системе свои 8 КБ данных, они будут записаны как можно скорее? Или это от чего-то зависит?

Alexander Ivanchenko 23.03.2022 17:56

Фактическая запись на диск может быть отложена ОС, но, как правило, когда другой процесс пытается прочитать файл, кеш ОС сбрасывается (или чтение выполняется из кеша), так что проблема здесь полностью внутри JVM, и тащить в нее ОС — ненужное усложнение.

Mark Rotteveel 23.03.2022 17:59

@MarkRotteveel Спасибо за объяснение. Я изменил ответ.

Alexander Ivanchenko 23.03.2022 18:11

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

Mark Rotteveel 23.03.2022 20:29

Когда буфер BufferedWriter заполнен, он просто передает данные базовому Writer, который по-прежнему является классом Java. В случае FileWriter он должен кодировать символы в байты, для чего требуется ByteBuffer. Только когда этот буфер заполнен (или происходит сброс/закрытие), фактические байты передаются FileOutputStream, который будет вызывать операционную систему). Поскольку для закодированных 8192 символов может потребоваться более 8192 байтов, возможно, что некоторые из них записываются, а остальные буферизуются в буфере байтов FileWriter, когда буфер BufferedWriter заполнен.

Holger 24.03.2022 10:48

@Holger Спасибо, что указали на эти детали, я обновил ответ.

Alexander Ivanchenko 25.03.2022 14:51

Другие вопросы по теме