14

私がファイルから読み取ることを目にするすべてのJava実装では、ほとんどの場合、ファイルリーダーが1行ずつ読み取るために使用されます。私の考えでは、これは回線ごとにシステムコールを必要とするため、非常に非効率的です。

代わりに私がやっていたのは、入力ストリームを使用してバイトを直接取得することです。私の実験では、これは非常に高速です。私のテストは1MBのファイルでした。

    //Stream method
    try {
        Long startTime = new Date().getTime();

        InputStream is = new FileInputStream("test");
        byte[] b = new byte[is.available()];
        is.read(b);
        String text = new String(b);
        //System.out.println(text);

        Long endTime = new Date().getTime();
        System.out.println("Text length: " + text.length() + ", Total time: " + (endTime - startTime));

    }
    catch (Exception e) {
        e.printStackTrace();
    }

    //Reader method
    try {
        Long startTime = new Date().getTime();

        BufferedReader br = new BufferedReader(new FileReader("test"));
        String line = null;
        StringBuilder sb = new StringBuilder();
        while ((line = br.readLine()) != null) {
            sb.append(line);
            sb.append("\n");
        }
        String text = sb.toString();

        Long endTime = new Date().getTime();
        System.out.println("Text length: " + text.length() + ", Total time: " + (endTime - startTime));

    }
    catch (Exception e) {
        e.printStackTrace();
    }

これにより、次の結果が得られます。

Text length: 1054631, Total time: 9
Text length: 1034099, Total time: 22

では、なぜ人々はストリームの代わりにリーダーを使用するのでしょうか?

テキストファイルを受け取り、すべてのテキストを含む文字列を返すメソッドがある場合、ストリームを使用してそれを行う方が必ずしも良いですか?

4

3 に答える 3

9

あなたはリンゴとバナナを比較しています。一度に1行を読み取ることは、bufferedReaderを使用しても、データをできるだけ速く取得するよりも効率が悪くなります。すべての状況で正確であるとは限らないため、availableの使用は推奨されないことに注意してください。暗号ストリームを使い始めたとき、私はこれを自分で見つけました。

于 2012-04-22T16:54:32.200 に答える
3

FileReaderBufferedReader特に、ファイルが明確に定義されたレコード構造を持ち、各レコードが1行に対応している場合は、ファイルを1行ずつ読み取ることが理にかなっていることが多いため、一般にaと組み合わせて使用​​されます。

また、javadocsFileReaderで述べられているように、文字エンコードと変換を処理するための作業の一部を簡素化できます。

文字ファイルを読むためのコンビニエンスクラス。このクラスのコンストラクターは、デフォルトの文字エンコードとデフォルトのバイトバッファーサイズが適切であると想定しています... FileReaderは、文字のストリームを読み取るためのものです。

于 2012-04-22T16:49:09.450 に答える
3

BufferedReaderバッファサイズを増やしてみてください。例えば:

BufferedReader br = new BufferedReader(new FileReader("test"),2000000);

適切なバッファサイズを選択すると、高速になります。

次に、サンプルでReaderStringBuilderの入力に時間を費やします。行を処理する必要がある場合は、ファイルを1行ずつ読み取る必要があります。ただし、文字列内のテキストのみを読み取る必要がある場合は、テキストのより大きなチャンクを読み取り、適切なサイズで初期化さpublic int read(char[] cbuf)れたチャンクを書き込みます。StringWriter

使用するか、パフォーマンスに依存しないかをInputStream選択します。Readerリーダーを使用すると文字セットをより簡単に処理できるため、通常はReaderテキストデータを読み取るときに使用します。

別のポイント、ここにあなたのコード

byte[] b = new byte[is.available()];
is.read(b);
String text = new String(b);

正しくありません。ドキュメントには

InputStreamの一部の実装はストリーム内の合計バイト数を返しますが、多くは返さないことに注意してください。このメソッドの戻り値を使用して、このストリーム内のすべてのデータを保持することを目的としたバッファーを割り当てることは決して正しくありません。

だから注意してください、あなたはそれを修正する必要があります。

于 2012-04-22T16:53:19.453 に答える