-1

ファイル リーダー関数を最適化したいのですが、try ループの外で null を宣言するのがベスト プラクティスかどうかわかりません。また、Stringbuffer に文字をループして追加することは悪い習慣と見なされますか? ここでは例外処理を使いたいのですが、別の仕組みを使った方が良いのではないでしょうか? どんなアドバイスでも大歓迎です、ありがとう。

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();
}

}

4

2 に答える 2

3

アドバイス:

  1. コードを適切にインデントします。あなたの質問の内容は、犬の朝食のようです。

  2. ftry / catch ブロック内で初期化する必要はありません。Exceptionコンストラクターは、使用している方法でスローすることはできません。

  3. 実際、それを宣言する必要はまったくありません。をインライン化するだけnew File(...)です。

  4. 実際、それを行う必要さえありません。FileReader(String)コンストラクターを使用します。

  5. StringBufferループ内を初期化しても意味がありません。潜在的なパフォーマンスの利点は小さく、ファイルが空であるか存在しないというエッジケースにのみ適用されます。それ以外の場合はすべて、これはアンチ最適化です。

  6. キャッチしないでくださいException。スローされると予想される例外をキャッチし、他のすべての例外が伝播できるようにします。予期しない例外は、プログラムのバグによるものであり、他のものとは異なる方法で処理する必要があります。

  7. 例外をキャッチしたら、証拠を捨てないでください。予期しない例外の場合は、例外、そのメッセージ、およびスタック トレースを出力/ログに記録するか、スローする例外の「原因」として渡します。

  8. は句FileReaderで閉じる必要があります。finallyコードのバージョンでは、オブジェクトが作成された後、呼び出しFileReaderの前に例外が発生した場合、 は閉じられません。close()これにより、ファイル記述子がリークし、後でアプリケーションで問題が発生する可能性があります。

  9. さらに良いのは、「リソース」を自動的に閉じる処理を行う新しい Java 7 の「try with resource」構文を使用することです (以下を参照)。

  10. 一度に 1 文字ずつファイルから読み取っています。これは非常に非効率的です。を でラップするか、または (たとえば) を使用して一度に多数の文字を読み取る必要がありReaderますBufferedReaderread(char[], int, int)

  11. スレッドセーフな文字列アセンブラが必要な場合を除き、...StringBuilderではなく使用してください。StringBuffer

  12. 例外をラップするRuntimeExceptionことは悪い習慣です。呼び出し元が特定の例外を処理するのが難しくなります...必要な場合...そして、適切な診断の出力さえも困難にします。(これは、コードのように元の例外を破棄しなかったことを前提としています。)

注: ポイント 9 ではなくポイント 8 のアドバイスに従う場合、ブロック内のファイルを開く場合にfrtoの初期化が必要であることがわかります。nulltry


これが私がこれを書く方法です:

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()してファイル サイズ (バイト単位) を調べ、それを .xml ファイルの初期サイズとして使用しますStringBuilder。ただし、通常、ファイルが小さい場合、アプリケーションの速度が低下する可能性があります。

于 2012-02-25T03:00:32.623 に答える
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% 以上の改善が得られます。同期が必要でない限り、文字列バッファの代わりに文字列ビルダーを使用してください。

10MBのファイルで50回実行し、平均しました

  • try 内に例外処理を必要としないものを入れる必要はありません
  • そのif句は必要ありません。これは1回だけ真になるため、時間を無駄にしているためです-すべての文字をチェックします
  • スローする実行時例外はありません。

結果: 最も速い組み合わせから最も遅い組み合わせ:

  1. 行ごとの文字列ビルダーとバッファリングされたリーダー: 211 ミリ秒
  2. 文字列バッファーとバッファー リーダーの行ごと: 213 ミリ秒
  3. 文字列ビルダーとバッファリングされたリーダー char ごと: 348 ミリ秒
  4. 文字列バッファとバッファリングされたリーダー文字ごと: 372 ミリ秒
  5. 文字列ビルダとファイル リーダー char by char: 878
  6. 文字列バッファとファイル リーダーの文字単位: 935 ミリ秒
  7. 文字列: 非常に遅い

そのため、文字列ビルダー + バッファー リーダーを使用し、1 行ずつ読み取って最良の結果を得ることができます。

于 2012-02-25T04:08:59.423 に答える