2012-02-25 5 views
-1

Я хочу оптимизировать функцию чтения файлов, но не уверен, что лучше всего объявить нули вне цикла try. Кроме того, цикл и добавление символов в Stringbuffer считается плохой практикой? Я хотел бы использовать здесь обработку исключений, но, возможно, лучше использовать другую структуру? любой совет приветствуется, спасибо.Нулевые объявления Filereader и передовая практика добавления

public String readFile(){ 
File f = null; 
FileReader fr = null; 
StringBuffer content = null; 
try{ 
f = new File("c:/test.txt"); 
fr = new FileReader(f); 
int c;   
while((c = fr.read()) != -1){    
if(content == null){ 
content = new StringBuffer(); 
} 

content.append((char)c); 
     } 

fr.close();   
    } 
catch (Exception e) { 
throw new RuntimeException("An error occured reading your file"); 
    }  
    return content.toString(); 
} 

}

ответ

3

Совет:

  1. Отступ ваш код правильно. Материал в вашем вопросе выглядит как завтрак собаки.

  2. Вам не нужно инициализировать f внутри блока try/catch. Конструктор не может выбрасывать Exception так, как вы его используете.

  3. Фактически, вам не нужно декларировать его вообще. Просто введите new File(...).

  4. Фактически, вам даже не нужно это делать. Используйте конструктор FileReader(String).

  5. Внутри петли нет смысла инициализировать StringBuffer. Потенциальное преимущество в производительности мало и применяется только в крайнем случае, когда файл пуст или не существует. Во всех остальных случаях это анти-оптимизация.

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

  7. Когда вы поймаете исключение, не выбрасывайте доказательства. Для неожиданного исключения либо распечатайте/запишите исключение, его сообщение и его стек, либо передайте его как «причину» исключаемого вами исключения.

  8. FileReader следует закрыть в статье finally. В вашей версии кода FileReader не будет закрыт, если возникло исключение после создания объекта и до вызова close(). Это приведет к утечке файлового дескриптора, а может вызвать проблемы позже в вашем приложении.

  9. Еще лучше, используйте новый синтаксис Java 7 «попробуйте с ресурсом», который автоматически закрывает «ресурс» (см. Ниже).

  10. Вы читаете из файла один символ за раз. Это очень неэффективно. Вам нужно либо обернуть Reader в BufferedReader, или читать большое количество символов, в то время, используя (например) read(char[], int, int)

  11. Использование StringBuilder вместо StringBuffer ... если не вам необходимости потокобезопасного строки ассемблер.

  12. Обертывание исключений в 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. Однако, если файлы, как правило, небольшие, это может замедлить работу приложения.

+0

'try (FileReader fr = new FileReader (" c: /test.txt "))' Является ли это законным в Java? Попробуйте без Catch? Попробуйте с параметрами? Кроме того, почему вы бросаете IOException, если у вас есть блок try/catch? Наконец, содержимое не доступно, когда вы его возвращаете. –

+0

Это законно в синтаксисе Java 7. Это не сработает на Java 6 или ранее. См. Здесь: http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html –

+0

@RyanAmos - 1) Да, это законный синтаксис Java 7. 2) Да, попытка без улова законна ... см. 1). 3) Да, см. 1). 4), потому что я НЕ ловил IOException. 5) Ой ... Я это исправлю. –

0
public String readFile() { 
    File f = new File("/Users/Guest/Documents/workspace/Project/src/test.txt"); 
    FileReader fr = null; 
    BufferedReader br = null; 
    StringBuilder content = new StringBuilder();; 
    try { 
     fr = new FileReader(f); 
     br = new BufferedReader(fr); 
     //int c; 
     //while ((c = fr.read()) != -1) { 
      //content.append((char) c); 
     //} 
     String line = null; 
     while((line = br.readLine()) != null) { 
      content.append(line); 
     } 
     fr.close(); 
     br.close(); 
    } catch (Exception e) { 
     // do something 

    } 
    return content.toString(); 
} 

Используйте буферный читатель и вы будете получать 70% + улучшение, использование строки построителя вместо строки буфер, если нет необходимости Syncronization.

побежал на файл 10МБ 50 раз и не усредняются

  • нет необходимости ставить что-либо, что не нуждается в обработку исключений внутри попытаться
  • нет необходимости в том, что если п, потому что это будет справедливо только один раз и поэтому вы тратите время - проверяя его для каждого символа
  • нет исключений для выполнения, которые нужно выполнить.

результаты: быстрый сочетание к самому медленному:

  1. строки строитель и забуференный читателя строка за строкой: 211 мс
  2. строковый буфер и буферизуется читатель строка за строкой: 213 мс
  3. строки строитель и буферизованный считывающий char char: 348 мс
  4. строковый буфер и буферный считыватель char по символу: 372 мс
  5. строка bui lder и чтения файлов символ на гольца: 878
  6. строковый буфер и файл для чтения символ на гольца: 935 мс
  7. строка: очень медленно

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

+0

@ StephenC, согласился! оставил его там от тестирования неправильного пути к файлу :) – Isaac

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

  • Нет связанных вопросов^_^