10

パフォーマンスの観点から比較InputStream.read()しようとしています。InputStream.read(byte[] b)

クラスのメソッドが単にメソッドを繰り返し呼び出すことをInputStream.read(byte[] b)考えると、何らかの方法で高速ですか?read(b, off, len)InputStreamread()

4

2 に答える 2

4

InputStreamのデフォルトの動作と、そのサブクラスのほとんどが行うことを混同しないでください。オブジェクト指向設計の原則は、サブクラスがその実装のメソッドの動作を変更できることです。

InputStreamから-read(byte [])はread()を繰り返し呼び出します。

public int read(byte b[], int off, int len) throws IOException {
   // code removed

        for (; i < len ; i++) {
            c = read();

   // code removed
}

BufferedInputStreamから-read(byte [])はread()を呼び出しません。

public synchronized int read(byte b[], int off, int len) throws IOException {
   // code removed
        int nread = read1(b, off + n, len - n);
   // code removed
}

private int read1(byte[] b, int off, int len) throws IOException {
   // code removed
            return getInIfOpen().read(b, off, len);
   // code removed
}

FileInputStreamから-read(byte [])はread()を呼び出しません。

public int read(byte b[], int off, int len) throws IOException {
    return readBytes(b, off, len);
}

private native int readBytes(byte b[], int off, int len) throws IOException;

InputStreamは一度に1バイトを読み取りますが、ほとんどすべての実装は、基礎となるストリームの同じメソッドにread(byte [])を渡します。

注:read(byte []、int、int)の実装は、3つのケースすべてで異なります。

私がもっと明確に尋ねるのは、次のとおりです。20バイトを読み取りたいとしましょう。一度に1バイトを読み取ると、ループ内で毎回基になるストリーム(ファイルシステムなど)にヒットします。これは、20回を意味します。一度にバイト、つまりread(byte [] 20)を使用すると、基になるストリーム(ファイルシステムなど)に1回または20回ヒットします。(与えられているように:read(byte [] b)メソッドもメソッドread()を20回繰り返し呼び出す)??

BufferedInputStreamまたはFileInputStreamのどちらを使用する場合でも、1回のread(byte [])により、最大で1回のシステムコールがbyte[]に読み込まれます。

于 2012-07-16T10:50:41.927 に答える
2

あなたのケースで最も便利だと思うものを使用してください、しかしあなたをで包むことを忘れないでInputStreamくださいBufferedInputStream

バッファリングを行わないread()と、読み取るたびに単一のストリームが基になるストリーム(ファイルシステムなど)にヒットします。同じものをバッファリングするとread()、チャンク(4KiBなど)がロードされ、バッファリングされます。明らかに、ディスクからの読み取りは(低レバーのOS /ハードディスクキャッシングが存在する場合でも)はるかに遅くなります。

したがってread(byte[] b)、ストリームがバッファリングされていない場合、または実際に複数のバイトを読み取りたい場合にのみ適しています。

于 2012-07-16T09:58:18.893 に答える