73

FileInputStream を使用してファイルを配列に読み込もうとしましたが、約 800 KB のファイルをメモリに読み込むのに約 3 秒かかりました。次に、FileInputStream を BufferedInputStream にラップする以外は同じコードを試しましたが、約 76 ミリ秒かかりました。まだバイト単位でファイルを読み取っているにもかかわらず、BufferedInputStream を使用すると、ファイルをバイト単位で読み取るのがはるかに高速になるのはなぜですか? コードは次のとおりです (残りのコードはまったく関係ありません)。これは「高速」コードであることに注意してください。「遅い」コードが必要な場合は、BufferedInputStream を削除できます。

InputStream is = null;

    try {
        is = new BufferedInputStream(new FileInputStream(file));

        int[] fileArr = new int[(int) file.length()];

        for (int i = 0, temp = 0; (temp = is.read()) != -1; i++) {
            fileArr[i] = temp;
        }

BufferedInputStream は 30 倍以上高速です。それよりもはるかに。では、なぜこれなのか、このコードをより効率的に (外部ライブラリを使用せずに) 行うことは可能でしょうか?

4

3 に答える 3

1

これは、ディスク アクセスのコストが原因です。サイズが 8kb のファイルがあるとします。BufferedInputStream なしでこのファイルを読み取るには、8*1024 回のアクセス ディスクが必要になります。

この時点で、BufferedStream が登場し、FileInputStream と読み取るファイルの間の仲介者として機能します。

ワンショットで、バイトのチャンクを取得します。デフォルトはメモリに 8kb であり、FileInputStream はこの仲介者からバイトを読み取ります。これにより、操作の時間が短縮されます。

private void exercise1WithBufferedStream() {
      long start= System.currentTimeMillis();
        try (FileInputStream myFile = new FileInputStream("anyFile.txt")) {
            BufferedInputStream bufferedInputStream = new BufferedInputStream(myFile);
            boolean eof = false;
            while (!eof) {
                int inByteValue = bufferedInputStream.read();
                if (inByteValue == -1) eof = true;
            }
        } catch (IOException e) {
            System.out.println("Could not read the stream...");
            e.printStackTrace();
        }
        System.out.println("time passed with buffered:" + (System.currentTimeMillis()-start));
    }


    private void exercise1() {
        long start= System.currentTimeMillis();
        try (FileInputStream myFile = new FileInputStream("anyFile.txt")) {
            boolean eof = false;
            while (!eof) {
                int inByteValue = myFile.read();
                if (inByteValue == -1) eof = true;
            }
        } catch (IOException e) {
            System.out.println("Could not read the stream...");
            e.printStackTrace();
        }
        System.out.println("time passed without buffered:" + (System.currentTimeMillis()-start));
    }
于 2017-07-12T19:28:23.780 に答える