2

次のコードではファイルをダウンロードできません (ところで clen はファイルの長さです)。

    int pos = 0, total_pos = 0;
    byte[] buffer = new byte[BUFFER_SIZE];
            while (pos != -1) {
                pos = in.read(buffer, 0, BUFFER_SIZE);
                total_pos += pos;
                out.write(buffer);
                setProgress((int) (total_pos * 100 / clen));
            }

...しかし、これはうまくいきます:

    int buf;
    while ((buf = in.read()) != -1)
        out.write(buf);

2 番目のコード セグメントはすばやく動作するのに、なぜだろうと思っています。その点で、byte[] バッファを使用する特定の理由はありますか (それは高速ではないようで、BufferedInputStream は既に独自のバッファを使用しているためです....?)

4

2 に答える 2

2

これがどのように行われるべきかです。

public static void copyStream(InputStream is, OutputStream os)
    {
        byte[] buff = new byte[4096];
        int count;
        try {
            while((count = is.read(buff)) > 0)
                os.write(buff, 0, count);

        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                if(is != null)
                    is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(os != null)
                    os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }
于 2011-10-11T03:52:51.977 に答える
0

コードを機能させるために必要な最小限の変更を加えようとしました。st0le は、ストリーム コピーのより適切なバージョンを提供するという点で優れた仕事をしました。

public class Test {
    private static final String FORMAT = "UTF-8";
    private static final int BUFFER_SIZE = 10; // for demonstration purposes.
    public static void main(String[] args) throws Exception {
        String string = "This is a test of the public broadcast system";
        int clen = string.length();
        ByteArrayInputStream in = new ByteArrayInputStream(string.getBytes(FORMAT));
        OutputStream out = System.out;
        int pos = 0, total_pos = 0;
        byte[] buffer = new byte[BUFFER_SIZE];
        while (pos != -1) {
            pos = in.read(buffer, 0, BUFFER_SIZE);
            if (pos > 0) {
                total_pos += pos;
                out.write(buffer, 0, pos);
                setProgress((int) (total_pos * 100 / clen));
            }
        }
    }
    private static void setProgress(int i) {
    }
}
  • バッファを出力ストリームに書き出すときに、 posの値を無視していました。
  • また、ファイルの末尾を読み取った可能性があるため、 posの値を再確認する必要があります。その場合、 total_posをインクリメントしません(ただし、おそらく 100% 完了したことを報告する必要があります)。
  • 適切な場所で close() を使用して、リソースを正しく処理してください。

-編集- 配列をバッファとして使用する一般的な理由は、出力ストリームがより大きなデータセットでできる限り多くの作業を実行できるようにするためです。

コンソールへの書き込みには大きな遅延はないかもしれませんが、書き込み中のネットワーク ソケットまたはその他の遅いデバイスである可能性があります。JavaDocの状態として

OutputStream の write メソッドは、書き出されるバイトごとに 1 つの引数の write メソッドを呼び出します。サブクラスは、このメソッドをオーバーライドして、より効率的な実装を提供することをお勧めします。

Buffered Input/Output Stream を使用する場合にこれを使用する利点は、おそらく最小限です。

于 2011-10-11T04:04:19.323 に答える