Я пытаюсь написать 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
строк.
Я не закрывал bufferedWritter как записывающее значение записи во время выполнения цикла. позвольте мне проверить это
2thanks, когда я закрою BufferedWriter
. он записывает весь текст в файл
Если решение, представленное в моем ответе, не решает вашу проблему или что-то неясно, оставьте комментарий.
Оно работает. мне удалить этот вопрос или оставить как есть? В любом случае, большое спасибо за улучшение вопроса
@eFortsHub Поскольку вопрос решен, он представляет собой пара проблема-решение и его стоит сохранить для будущих читателей. Итак, определенно Оставь это.
данные, который вы записываете в выходной поток не гарантируется, чтобы немедленно достичь места назначения.
BufferedWritter
— это так называемый поток высокого уровня, который украшает базовый поток, который имеет дело с конкретным пунктом назначения данных, например FileWriter
(и между ними может быть еще несколько потоков), путем буферизации вывода текста и предоставления метода убеждения newLine()
.
BufferedWritter
поддерживает буфер (массив символов) с размером по умолчанию 8192
. И когда это наполняется, он передает его базовому низкоуровневый поток. В данном случае к FileWriter
, который позаботится о кодировании персонажи в байты.
Когда это будет сделано, JVM передаст данные Операционная система через FileOutputStream
(потому что под капотом потоки символов строятся поверх потоков укусов).
Итак, данные, записанные в буфер, появятся в файл в куски:
Javadoc для метода close()
говорит:
Closes the stream, flushing it first.
т.е. перед освобождением ресурса close()
вызывает метод flush()
, который принудительно передает кэшированные данные по назначению.
Если исключения не возникнет, все, что было записано в поток, гарантированно достигнет места назначения при закрытии потока.
Вы также можете использовать flush()
в своем коде. Но применять его нужно с большой осторожностью. Вероятно, когда вы имеете дело с большими объемами критических данных и что полезно, даже если они частично записаны (поэтому в случае исключения вы потеряете меньше информации). Неправильное использование flush()
может значительно снизить производительность.
@MarkRotteveel Я знаю это. Итак, когда BufferedWriter
передаст системе свои 8 КБ данных, они будут записаны как можно скорее? Или это от чего-то зависит?
Фактическая запись на диск может быть отложена ОС, но, как правило, когда другой процесс пытается прочитать файл, кеш ОС сбрасывается (или чтение выполняется из кеша), так что проблема здесь полностью внутри JVM, и тащить в нее ОС — ненужное усложнение.
@MarkRotteveel Спасибо за объяснение. Я изменил ответ.
Дубликаты автоматически удаляются только в том случае, если на вопрос нет ответов. Иногда люди будут голосовать за удаление дубликатов, но это не то, что обычно следует делать (дубликаты служат указателями на другой вопрос). Однако, если вы хотите, вы можете удалить свой ответ здесь и опубликовать его на дубликате.
Когда буфер BufferedWriter
заполнен, он просто передает данные базовому Writer
, который по-прежнему является классом Java. В случае FileWriter
он должен кодировать символы в байты, для чего требуется ByteBuffer
. Только когда этот буфер заполнен (или происходит сброс/закрытие), фактические байты передаются FileOutputStream
, который будет вызывать операционную систему). Поскольку для закодированных 8192 символов может потребоваться более 8192 байтов, возможно, что некоторые из них записываются, а остальные буферизуются в буфере байтов FileWriter
, когда буфер BufferedWriter
заполнен.
@Holger Спасибо, что указали на эти детали, я обновил ответ.
Для меня это звучит так, как будто вы неправильно закрываете
BufferedWriter
. Можете ли вы показать, как вы открываете и закрываете его?