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

Является ли java.io.BufferedOutputStream безопасным для использования?

На первый взгляд этот код выглядит вполне нормально

BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream("1.txt"));
byte[] bytes = new byte[4096];
bout.write(bytes);
bout.close();

но если мы рассмотрим более подробно, мы увидим, что close() реализуется следующим образом

public void close() throws IOException {
    try {
      flush();
    } catch (IOException ignored) {
    }
    out.close();
}

Возможно ли, что из-за ошибок flush() игнорируются данные могут быть потеряны, и программа не заметит этого? В FilterOutputStream.close не упоминается какая-либо опасность (где BufferedOutputStream наследует close() from) API.

ОБНОВЛЕНИЕ: Чтобы имитировать ошибку ввода-вывода во время закрытия(), я сменил тест на запись во флэш-память, добавив 5 секунд сна перед bout.close(), и пока тест спал, я удалил Flash от USB. Тест завершился без исключений, но когда я вставил Flash и проверил его - 1.txt не было.

Затем я перевернул close()

    BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream("g:/1.txt")) {
        @Override
        public void close() throws IOException {
            flush();
            super.close();
        }
    };

и снова проверил тест и получил

Exception in thread "main" java.io.FileNotFoundException: g:\1.txt (The system cannot the specified path)
    at java.io.FileOutputStream.open(Native Method)
    at java.io.FileOutputStream.<init>(FileOutputStream.java:212)
    at java.io.FileOutputStream.<init>(FileOutputStream.java:104)
    at test.Test1.main(Test1.java:10)
4b9b3361

Ответ 1

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

Достойная альтернатива, хотя и прилагает усилия со стороны программиста, заключается в вызове flush явно до close (правильная обработка потенциального IOException), как указано в комментарии от @Tom, особенно в блоке try/finally.

Эта проблема может быть еще более усугублена в Java7 из-за объектов AutoCloseable, так как вы явно не вызываете метод close(), и этот вид работы еще проще проскальзывать.