Я обнаружил два случая:
- Потеря сетевого подключения, когда в буфере все еще есть данные для очистки.
- Заполнение файловой системы (или достижение вашего пользовательского лимита для размера файла), когда в буфере еще есть данные для очистки.
Оба эти примера зависят от того, что происходит, пока в буфере еще есть данные. Close сбрасывает буфер перед закрытием файла, поэтому, если при записи данных в файл возникает ошибка, возникает исключение IOException.
Если вы выполните следующий код, передав ему имя файла для создания на сетевом диске, а затем, прежде чем нажать клавишу ввода, отсоедините сетевой кабель, это приведет к тому, что программа сбросит IOException при закрытии.
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
public class Test
{
public static void main(final String[] argv)
{
final File file;
file = new File(argv[0]);
process(file);
}
private static void process(final File file)
{
Writer writer;
writer = null;
try
{
writer = new FileWriter(file);
writer.write('a');
}
catch(final IOException ex)
{
System.err.println("error opening file: " + file.getAbsolutePath());
}
finally
{
if(writer != null)
{
try
{
try
{
System.out.println("Please press enter");
System.in.read();
}
catch(IOException ex)
{
System.err.println("error reading from the keyboard");
}
writer.close();
}
catch(final IOException ex)
{
System.err.println("See it can be thrown!");
}
}
}
}
}
Начиная с Java 7 вы можете использовать try-with-resources, чтобы выйти из этого беспорядка (удален явный код генерации исключений для операции close()
):
private static void process(final File file) {
try (final Writer writer = new FileWriter(file)) {
writer.write('a');
} catch (final IOException e) {
// handle exception
}
}
это автоматически обрабатывает исключения в close()
и выполняет внутреннюю проверку null
.