Представьте, что MyOpenedFile — это некий файл-обертка с открытыми потоками. Затем предположим, что этот код:
// method in an Util class
static void safeClose(MyOpenedFile f) {
if (f != null) {
try {
f.close();
} catch(IOException ex) { /* add logging or console output */ }
}
}
Фактический метод для вопроса:
void doSomeFileOperation(...) throws IOException, ... {
MyOpenedFile f1 = null;
MyOpenedFile f2 = null;
try {
/* method's "business logic" code beings */
f1 = new MyOpenedFile(...);
//do stuff
f2 = new MyOpenedFile(...);
// do stuff
f1.close(); f1 = null;
// do stuff with f1 closed
f2.close(); f2 = null;
// do stuff with f2 closed
/* method's "business logic" code ends */
} finally {
Util.safeClose(f1); f1 = null;
Util.safeClose(f2); f2 = null;
}
}
Теперь это довольно беспорядочно и особенно подвержено ошибкам (например, некоторый код в блоке finally может быть очень трудно вызвать в модульных тестах). Например, в C++ деструктор позаботится об очистке (будь то вызов деструктора указателя с областью действия или напрямую), и код будет намного чище.
Итак, есть ли лучший/лучше/чище способ обернуть приведенный выше фрагмент кода бизнес-логики, чтобы любые исключения распространялись, но оба файла f1
и f2
закрывались (или, по крайней мере, предпринималась попытка закрытия обоих, даже если это не удается)?
Также приветствуются ответы, указывающие на любые библиотеки с открытым исходным кодом, такие как Apache Commons, предоставляющие хорошие оболочки.
close
илиsafeClose
перед всемиnull
заданиями. - person hyde   schedule 01.11.2012close
дважды для каждого файла (в попытке и в конце)? - person home   schedule 01.11.2012flush()
, не обязательно закрыватьf1
илиf2
, прежде чем вы закончите с методом. Кроме того, если этот классMyOpenedFile
написан вами, вы можете легко заставить его вызывать толькоclose()
в базовом потоке при первом вызове, устраняя необходимость в методеsafeClose
. - person Thor84no   schedule 01.11.2012