Совет:
Правильный отступ вашего кода. Материал в вашем вопросе выглядит как собачий завтрак.
Вам не нужно инициализировать f
внутри блока try / catch. Конструктор не может выбросить Exception
так, как вы его используете.
На самом деле, вам вообще не нужно это объявлять. Просто вставьте new File(...)
.
На самом деле, вам даже не нужно этого делать. Используйте конструктор FileReader(String)
.
Нет смысла инициализировать StringBuffer
внутри цикла. Потенциальный выигрыш в производительности невелик и применяется только в крайнем случае, когда файл пуст или не существует. Во всех остальных случаях это антиоптимизация.
Не поймать Exception
. Поймайте исключения, которые вы ожидаете выбросить, и разрешите распространяться всем остальным исключениям. Неожиданные исключения будут вызваны ошибками в вашей программе и должны обрабатываться иначе, чем другие.
Когда вы поймаете исключение, не выбрасывайте улики. В случае непредвиденного исключения либо напечатайте / запишите исключение, его сообщение и трассировку стека, либо передайте его как «причину» исключения, которое вы выбросили.
FileReader
следует закрыть в предложении finally
. В вашей версии кода FileReader
не будет закрыт, если есть исключение после создания объекта и до вызова close()
. Это приведет к утечке файлового дескриптора, и может вызвать проблемы позже в вашем приложении.
Еще лучше, используйте новый синтаксис Java "try with resource", который обеспечивает автоматическое закрытие "ресурса" (см. Ниже).
Вы читаете из файла по одному символу за раз. Это очень неэффективно. Вам нужно либо обернуть Reader
в BufferedReader
, либо прочитать одновременно большое количество символов, используя (например) read(char[], int, int)
Используйте StringBuilder
вместо StringBuffer
... если только вам не нужен поточно-ориентированный сборщик строк.
Упаковывать исключения в RuntimeException
- это плохая практика. Для вызывающего абонента трудно обрабатывать определенные исключения ... если это необходимо ... и даже затрудняется печать приличной диагностики. (И это предполагает, что вы не выбросили исходное исключение, как это делает ваш код.)
Примечание: если вы будете следовать советам пункта 8, а не 9, вы обнаружите, что инициализация от fr
до null
необходима, если вы откроете файл в блоке try
.
Вот как бы я написал это:
public String readFile() throws IOException {
// Using the Java 7 "try with resource syntax".
try (FileReader fr = new FileReader("c:/test.txt")) {
BufferedReader br = new BufferedReader(fr);
StringBuilder content = new StringBuilder();
int c;
while ((c = br.read()) != -1) {
content.append((char)c);
}
return content.toString();
}
}
Дальнейшая оптимизация будет заключаться в использовании File.length()
для определения размера файла (в байтах) и использования его в качестве начального размера StringBuilder
. Однако, если файлы обычно небольшие, это может замедлить работу приложения.