web-dev-qa-db-ja.com

閉じたInputStreamを2回使用する必要がある場合、どうすれば再開できますか

現在、サーバーからJSON応答を取得するためにInpuStreamを使用しています。

私は2つのことをする必要があります:

  1. それを解析し、画面に値を表示します
  2. このフィードをSDCardファイルに保存します

これらの2つの方法を1つずつ使用しても、まったく問題はありません。

解析はGSONで行われます。

Gson gson = new Gson();
Reader reader = new InputStreamReader (myInputStream);
Result result = gson.FrmJson(reader, Result.class)

sDカードへのコピーは

FileOutputStream f (...) f.write (buffer)

それらの両方がテストされています。

問題は、解析が完了したら、SDCardに書き込みたいのですが、壊れてしまいます。 InputStreamが閉じていることを理解していますが、それが問題です。

ここに私の質問に近いものがあります: 複数の使用のためにInputStreamをキャッシュする方法

そのソリューションを改善し、使用できるものを提供する方法はありますか?

16
Waza_Be

おそらく、ByteArrayOutputStreamを使用して入力ストリームをbyte[]に排出し、ストリームを再読み取りする必要があるたびに、結果に基づいて新しいByteArrayInputStreamを作成します。

このようなもの:

ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int n = 0;
while ((n = myInputStream.read(buf)) >= 0)
    baos.write(buf, 0, n);
byte[] content = baos.toByteArray();

InputStream is1 = new ByteArrayInputStream(content);
... use is1 ...

InputStream is2 = new ByteArrayInputStream(content);
... use is2 ...

関連する、そしておそらく役立つ質問と回答:

29
aioobe

あるいは、私はそれを達成するためのこの素晴らしい方法を見つけました:

import Java.io.ByteArrayInputStream;
import Java.io.ByteArrayOutputStream;
import Java.io.IOException;
import Java.io.InputStream;

public class CopyInputStream
{
    private InputStream _is;
    private ByteArrayOutputStream _copy = new ByteArrayOutputStream();

    /**
     * 
     */
    public CopyInputStream(InputStream is)
    {
        _is = is;

        try
        {
            copy();
        }
        catch(IOException ex)
        {
            // do nothing
        }
    }

    private int copy() throws IOException
    {
        int read = 0;
        int chunk = 0;
        byte[] data = new byte[256];

        while(-1 != (chunk = _is.read(data)))
        {
            read += data.length;
            _copy.write(data, 0, chunk);
        }

        return read;
    }

    public InputStream getCopy()
    {
        return (InputStream)new ByteArrayInputStream(_copy.toByteArray());
    }
}

そして私はそれを

CopyInputStream cis = new CopyInputStream(input);
InputStream input1 = cis.getCopy();
0
Waza_Be