Согласен, весьма распространненная ошибка.
Вот даже при конфигурации log4j надо указывать не \n, а $n, иначе переводы строк будут не те и лог смотреть будет не приятно
Здравствуйте, aefimov, Вы писали:
A>Вот даже при конфигурации log4j надо указывать не \n, а $n, иначе переводы строк будут не те и лог смотреть будет не приятно
Ой, а можно чуть подробнее, гед надо указывать. Спасибо.
1. Если надо писать строки, то имхо использование Writer более наглядно, чем использование OutputStream;
2. Я бы не кидал checked exception наружу, т.е. либо тупо логировать его, либо оборачивать в unchecked;
3. В зависимости от задачи (в случае, когда надо писать отдельные строки) возможно изменение String[] на String ... может быть более удобным пользователю;
Итого:
public void writeLines(File file, String encoding, String ... lines) throws IllegalStateException {
try {
writeLinesImpl(file, encoding, lines);
} catch (IOException e) {
throw new IllegalStateException("Unexpected exception occured during writing to file. File: "
+ file.getAbsolutePath() + ", data to write: " + Arrays.toString(lines));
}
}
private void writeLinesImpl(File file, String encoding, String ... lines) throws IOException {
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), encoding));
try {
for (String line : lines) {
writer.write(line);
writer.newLine();
}
// writer.flush(); // implicitly called at writer.close() invocation
} finally {
writer.close();
}
}
Исходный код мне импонировал больше своей лаконичностью. Хотя конечно же надо ещё смотреть на то где этот метод используется.
B> throw new IllegalStateException("Unexpected exception occured during writing to file. File: " B> + file.getAbsolutePath() + ", data to write: " + Arrays.toString(lines));
Эй, а cause? Так по логам нельзя будет восстановить причину ошибки.
B>1. Если надо писать строки, то имхо использование Writer более наглядно, чем использование OutputStream; B>2. Я бы не кидал checked exception наружу, т.е. либо тупо логировать его, либо оборачивать в unchecked; B>3. В зависимости от задачи (в случае, когда надо писать отдельные строки) возможно изменение String[] на String ... может быть более удобным пользователю;
Что касается 1 и 3. согласен. А вот 2 -- спорный пункт. Совершенно не факт, что в данном случае с IOException'ом нужно обязательно что-то сделать. Вполне возможно, что данный writeLines -- это не единственный утилитный метод, а есть еще readLines и еще некоторое количество подобных методов, которые используются совместно в неком методе performSomeHighLevelWork, который, кстати, может сам может использовать низкоуровневое Java IO API. Поэтому, вместо того, чтобы в каждом из методов типа writeLines писать
} catch (IOException e) {
throw new IllegalStateException("Unexpected exception occured during blah-blah-blah", e);
}
может оказаться проще написать это один раз в performSomeHighLevelWork. Ну и естественно, не забыть cause.
Здравствуйте, dshe, Вы писали:
D>Что касается 1 и 3. согласен. А вот 2 -- спорный пункт. Совершенно не факт, что в данном случае с IOException'ом нужно обязательно что-то сделать. Вполне возможно, что данный writeLines -- это не единственный утилитный метод, а есть еще readLines и еще некоторое количество подобных методов, которые используются совместно в неком методе performSomeHighLevelWork, который, кстати, может сам может использовать низкоуровневое Java IO API. Поэтому, вместо того, чтобы в каждом из методов типа writeLines писать D>
D> } catch (IOException e) {
D> throw new IllegalStateException("Unexpected exception occured during blah-blah-blah", e);
D> }
D>
D>может оказаться проще написать это один раз в performSomeHighLevelWork.
Это да, лень — одно из оснвных достоинств разрабочика. Понятно, что не бывает универсального решения, которое было бы лучшим во всех ситуациях. Мое предложение относится к 'standalone method'.
Здравствуйте, bolshik, Вы писали:
MAP>>Что-то не понял для чего так оборачивать метод writeLinesImpl и почему не кидать IOException наерх?
B>Потому что IOException — checked exception.
А в чём проблема то? Там, наверху, в зависимости от того, что и куда пишем, сами разберутся, что с исключением делать.
По коду. Если возникло исключение во время работы методов write, то, возможно, будет исключение и при попытке закрыть поток, но так как закрытие находится в блоке finally, то исключение от попытки закрытия потока подавит "настоящее" исключение, то есть возможно потеряется истинная причина исключительной ситуации.
Здравствуйте, Donz, Вы писали:
D>А в чём проблема то? Там, наверху, в зависимости от того, что и куда пишем, сами разберутся, что с исключением делать.
В том, что неудобно. Там, наверху, должны сами решать, хотят они обрабатывать эксепшн или не хотят (мы со своей стороны четко прописываем IllegalStateException в сигнатуре, плюс пишем джавадок, т.е. даем всю необходимую информацию). В случае же с checked exception наверху должны всегда производить обработку.
D>По коду. Если возникло исключение во время работы методов write, то, возможно, будет исключение и при попытке закрыть поток, но так как закрытие находится в блоке finally, то исключение от попытки закрытия потока подавит "настоящее" исключение, то есть возможно потеряется истинная причина исключительной ситуации.
Да, теоретически возможно, но, имхо, в данном случае преимущество обработки такой ситуации меньше, чем увеличение объема и уменьшение читабельности кода, необходимого для этого.
Здравствуйте, bolshik, Вы писали:
B>Здравствуйте, Donz, Вы писали:
D>>А в чём проблема то? Там, наверху, в зависимости от того, что и куда пишем, сами разберутся, что с исключением делать.
B>В том, что неудобно. Там, наверху, должны сами решать, хотят они обрабатывать эксепшн или не хотят (мы со своей стороны четко прописываем IllegalStateException в сигнатуре, плюс пишем джавадок, т.е. даем всю необходимую информацию). В случае же с checked exception наверху должны всегда производить обработку.
А что мешает им кинуть выше? Ведь checked на то и checked чтобы обратить внимание на то, что метод не может принять решение что делать дальше. Т.е. сами по себе checked конечно не панацея, но отказываться от них полностью — суть зло.
Я обычно руководствуюсь простыми правилами:
1. Утилитный класс или внутренняя логика — checked
2. Компонентный (например dao) — unchecked либо один большой checked