В Java, когда я вызываю OutputStream.close (), мне всегда нужно вызывать OutputStream.flush () раньше?

Если я просто вызову close() в выходном streamе, выход будет гарантирован, или мне нужно всегда называть flush() ?

Close () всегда сбрасывается, поэтому нет необходимости звонить.

EDIT: Этот ответ основан на здравом смысле и на всех встречах, с которыми я столкнулся. Кто собирается внедрить close () для буферизованного streamа без сброса буфера первым? Нет вреда для вызова flush прямо перед close (). Однако есть последствия, если flush () называется чрезмерно. Он может победить под механизмом буферизации.

В то время как close должно вызвать flush , это немного сложнее, чем это …

Во-первых, декораторы (такие как BufferedOutputStream ) распространены в Java. Конструкция декоратора может потерпеть неудачу, поэтому вам нужно close «сырой» stream в блоке finally чья try включает в себя декоратор. В случае исключения вам обычно не нужно close декоратор (за исключением, например, для плохо реализованных декораторов сжатия). Обычно вам нужно flush декоратор в случае исключения. Следовательно:

 final RawOutputStream rawOut = new RawOutputStream(rawThing); try { final DecoratedOutputStream out = new DecoratedOutputStream(rawOut); // ... stuff with out within ... out.flush(); } finally { rawOut.close(); } 

В довершение всего, методы close декоратора часто выполняются неправильно. Это касается некоторых в java.io до недавнего времени.

Конечно, вы, вероятно, захотите использовать Execute Around idiom, чтобы сохранить DRY (ish).

Если вы хотите, чтобы stream был сброшен, тогда да , вызовите flush() перед вызовом функции close() .

Несмотря на все другие ответы на обратное (но, как было отмечено правильно в некоторых комментариях), реализация java.io.OutputStream::close() по умолчанию не вызывает flush() . Фактически, он ничего не делает. Если у вас есть дистрибутив источника, вы можете легко проверить его сами, иначе просто доверьтесь официальному javadoc , указанному здесь:

Общий договор закрытия заключается в том, что он закрывает выходной stream. Закрытый stream не может выполнять выходные операции и не может быть повторно открыт.

Закрытый метод OutputStream ничего не делает.

Независимо от того, сбрасывается ли close() или нет, самым безопасным подходом должно быть ручное ручное управление. Если он снова вспыхнет, кому это нужно?

Ответ «Tom Hawtin – tackline» содержит дополнительную информацию о безопасном закрытии streamов (но на самом деле не отвечает на исходный вопрос ясно = P).

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

Прежде всего. Проверьте их.

  • AutoCloseable#close()
  • Closeable#close()
  • OutputStream#close()
  • Writer#close()

Вы обнаружите, что нет единственного утверждения, что выражение close() вызовет flush() . Исправьте меня, если я пропустил.

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

flush() имеет свои собственные цели.

 // client // sends exactly 234 bytes // and returns exactly 124 bytes from the server static byte[] sendAndReceive(final OutputStream output, final InputStream input) throws IOException { final byte[] request = new byte[234]; output.write(request); // output.flush(); // @@? is this required or not? final byte[] response = new byte[124]; new DataInputStream(input).readFully(response); return response; } // server // recieve exactly 234 bytes from the client // sends exactly 124 bytes static void receiveAndSend(final InputStream input, final OutputStream output) throws IOException { final byte[] request = new byte[234]; new DataInputStream(input).readFully(request); final byte[] response = new byte[124]; output.write(response); // output.flush(); // @@? is this required or not? } 

Вещи, возможно, были изменены, но я испытал для себя около десяти лет назад. Выше исходный код (клиент) работал с Windows XP и не удался с Windows 2000 Server для одной и той же конечной точки (сервера).

И (вы) не должны (полагаться) на какое-либо конкретное поведение реализации close() .

 static void writeFile(File file, byte[] bytes) throws IOException { try (OutputStream out = new FileOutputStream(bytes)) { out.write(bytes); out.flush(); // who cares what FileInputStream#close does? } } 

Также обратите внимание, что flush() не означает запись / отправку ваших данных на физический диск или удаленную конечную точку. Это, в основном, просто сбрасывает буферные данные в JVM в базовую ОС.


описки

Writer#close() явно говорит, что это

закрывает stream, сначала промывая его.

Но это не значит, что все подclassы сохраняют этот корневой контракт. См. PrintWriter#close() который (без flush() ) закрывает внутренний out ( Writer ), который, опять же, зависит от реализации out ‘s close() .

Потоки представляют ресурсы, которые вы должны всегда очищать явно, вызывая метод close. Некоторые classы java.io (по-видимому, только classы вывода) include метод flush . Когда метод close вызывается для такого classа, он автоматически выполняет флеш. Нет необходимости явно вызывать flush перед вызовом close .

  • Суперclass «javax.servlet.http.HttpServlet» не найден на пути сборки Java
  • Как вызвать функцию или процедуру Oracle с помощью Hibernate (EntityManager) или JPA 2
  • Как рандомизировать два ArrayLists таким же образом?
  • Переопределение частных методов в Java
  • Можете ли вы использовать @Autowired со статическими полями?
  • @Transactional (распространение = Propagation.REQUIRED)
  • Самый простой способ обновить eclipse от 3.7 до 4.2 (Juno)
  • Java 8 группировка с использованием пользовательского коллектора?
  • Проблема с файловым перезаписыванием файлов вместо добавления в конец
  • Исключение Null Pointer при использовании Java Compiler API
  • XML-документ для строки
  • Давайте будем гением компьютера.