2016-11-06 4 views
0

Нужно ли мне закрыть FileOutputStream в следующем примере? И почему?Нужно ли закрывать поток?

FileOutputStream fos = new FileOutputStream("bytes.info"); 
ObjectOutputStream oos = new ObjectOutputStream(fos); 
oos.writeObject(data); 
oos.close(); 
+2

Если вы имеете в виду 'OutputStream', то ** да ** вы определенно делаете. Вы должны на самом деле ** всегда ** использовать [try-with-resources] (https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html). –

+0

Хотя я бы предложил использовать оператор try-with-resources, 'oos.close()' все равно закроет 'FileOutputStream'. –

+0

@BoristheSpider, почему этот парень не закрывает его в статье [http://www.ibm.com/developerworks/java/library/j-5things1/index.html?S_TACT=105AGX99&S_CMP=CP] – furry

ответ

2

Если исключений не было выбрано, то FileOutputStream будет закрыт ooo.close().

Исключение, заброшенное в writeObject, предотвратит закрытие любого из потоков. Таким образом, вызов close должен быть в блоке finally.

Есть дополнительная проблема, связанная с тем, что ObjectOutputStream может генерировать исключение в своем конструкторе. Он записывает заголовок потока в конструкторе, который может вызвать исключение. В этом случае необходимо закрыть FileOutputStream, но вызов oos.close() невозможен, потому что нет ссылки на ObjectOutputStream. Таким образом, вам действительно нужны два отдельных вызова: close, по одному для каждого потока, как в блоках finally.

Использование примерочных с-ресурсов берет на себя все это для вас:

try(
    FileOutputStream fos = new FileOutputStream("bytes.info"); 
    ObjectOutputStream oos = new ObjectOutputStream(fos) 
) { 
    oos.writeObject(data); 
} 
2

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

FileOutputStream управляет собственными ресурсами, которые освобождаются методом close. У класса также есть финализатор, который также выпускает ресурсы. Как часть освобождения собственных ресурсов, поток завершает запись буферизованных данных, если они есть. Однако, поскольку JVM не гарантирует, что финализатор будет вызываться для каждого объекта, отказ в вызове close создает риск оставить незаписанные буферизованные данные.

0

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

try (FileOutputStream fos = new FileOutputStream("bytes.info"); 
ObjectOutputStream oos = new ObjectOutputStream(fos));{ 

}catch(){} 

На всякий случай, если вы не используете попытку с ресурсами, закройте потоки файлов в блоке finally вручную.

FileOutputStream fos = null; 
ObjectOutputStream oos = null; 

try{ 
     fos = new FileOutputStream("bytes.info"); 
     oos = new ObjectOutputStream(fos)); 

     oos.writeObject(data); 
    }catch(){ 
    }finally{ 
     if(fos != null){ 
     fos.close(); 
     } 
     if(oos != null){ 
     oos.close(); 
     } 
    } 

Необходимо проверить, являются ли эти файловые потоки нулевыми или нет. Потому что, если они равны нулю, тогда будет другая ошибка. Тем не менее, лучше использовать try с ресурсами.

+1

[Closeable] (https://docs.oracle.com/javase/7/docs/api/java/io/Closeable.html) '.close()' может вызывать 'IOException', поэтому ваш второй блок должен каким-то образом с случаем 'fos.close()' бросать его. –

Смежные вопросы