読者です 読者をやめる 読者になる 読者になる

Re: InputStreamからStringへの変換

java

こんなんでいいのかな。

InputStreamからStringへの変換 - Humanity

(該当部分を抜粋)

    static String convertInputStreamToString(InputStream is) {
        final int n = 1024;
        byte[] b = new byte[n];
        StringBuffer buf;
        while (is.read(b, 0, n) != -1) {
            buf.append(new String(b));
        }
        return buf.toString();
    }

残念ながらダメダメです。

1024 バイト単位なので、マルチバイト文字の境界がここに来ると文字が壊れる

マルチバイト文字が 1024 バイト目と 1025 バイト目に来ていた場合、見事に分断されて文字が壊れる。

最後の読み込み時に、末尾にゴミが残る

例えば入力が 1025 バイトあった場合、最初に 1024 バイトをバッファに読み込んで、次に同じバッファに 1 バイトだけ読み込むことになる。そうすると残りの 1023 バイト分に最初のバッファが残っていて、そこもそのまま文字列になってしまう。

大抵の場合は StringBuilder を使うべき

CLDC 縛りとかそういった特殊な事情でもない限りは StringBuilder を使うべき。StringBuilder は StringBuffer の同期を行わない版で速いので、スレッドが絡まない場合は StringBuilder の方がいい。

解答例

文字列を扱いたい場合は Reader を使うのが正解。

    static String convertInputStreamToString(InputStream is) throws IOException {
        InputStreamReader reader = new InputStreamReader(is);
        StringBuilder builder = new StringBuilder();
        char[] buf = new char[1024];
        int numRead;
        while (0 <= (numRead = reader.read(buf))) {
            builder.append(buf, 0, numRead);
        }
        return builder.toString();
    }

ところで、任意の Reader から全部読み込んで String にするって結構やりそうなもんなんだけど、もっと簡単な方法はないのだろうか。ちょっと調べてみたけどみつからなかった…。