2

InputStreams を使用しているという既存の問題があり、このチャネルからの読み取りのパフォーマンスを向上させたいと考えています。したがって、私は で読みますReadableByteChannel

その結果、次のコードを使用すると読み取りがはるかに高速になります。

public static String readAll(InputStream is, String charset, int size) throws IOException{

    try(ByteArrayOutputStream bos = new ByteArrayOutputStream()){
        java.nio.ByteBuffer buffer = java.nio.ByteBuffer.allocate(size);

        try(ReadableByteChannel channel = Channels.newChannel(is)){

            int bytesRead = 0;

            do{
                bytesRead = channel.read(buffer);
                bos.write(buffer.array(), 0, bytesRead);
                buffer.clear();
            }
            while(bytesRead >= size);
        }
        catch(Exception ex){
            ex.printStackTrace();
        }
        String ans = bos.toString(charset);
        return ans;
    }
}

問題は:毎回最後まで読まない! ファイルを読み取ろうとすると、かなりうまく機能します。ネットワークソケットから読み取ると(たとえば、手動でWebページをリクエストするために)、途中で停止することがあります。

最後まで読むにはどうしたらいいですか?

私はこのようなものを使いたくありません:

StringBuilder result = new StringBuilder();
while(true){
    int ans = is.read();
    if(ans == -1) break;
    result.append((char)ans);
}
return result.toString();

この実装は遅いためです。

私の問題を解決できることを願っています。私のコードに間違いがあるかもしれません。

4

2 に答える 2

0

あなたのコピーループは完全に間違っています。であるbytesReadべき理由はなく、ストリームの最後で誤動作します>= size次のようになります。

while ((bytesRead = channel.read(buffer)) > 0)
{
    bos.write(buffer.array(), 0, bytesRead);
    buffer.clear();
}

転送をsizeバイトに制限するための適切な調整を行いますが、これは自明ではありません。

しかし、これらすべてを既存のものの上に重ねることは、時期尚早の終了がない限り、直接InputStream使用するよりもおそらく「はるかに高速」になることはありません。InputStreamを使用するというあなたの考えがあなたが投稿したものでない限りInputStream、それは恐ろしく遅いです。' で試してみてくださいBufferedInputStream

于 2015-11-25T18:48:04.940 に答える