В Java, когда я вызываю OutputStream.close (), мне всегда нужно вызывать OutputStream.flush () раньше?
Если я просто вызову close()
в выходном streamе, выход будет гарантирован, или мне нужно всегда называть flush()
?
- Что определяет потребительское смещение Кафки?
- list.clear () vs list = new ArrayList ();
- Что такое проверенные исключения в Java / C #?
- Как заполнить данные в JTable с помощью базы данных?
- Как я могу инициализировать статическую карту?
- Java - вызов имени метода при реализации интерфейса
- Зачем использовать сессионные компоненты без состояния?
- Java-swing прослушивает действие в текстовом поле формы
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 .