18

I am currently using an InpuStream to get a JSON response from my server.

I need to do 2 things with:

  1. Parsing it and displaying the values on the screen
  2. Save this feed on SDCard file

That gives me no issues at all when using these 2 methods one by one.

The parsing is made with GSON:

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

and the copy to SDCard is made with

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

Both of them have been tested.

TYhe problem is once the parsing is done, I want to write to SDCard and it breaks. I understand that my InputStream is closed, and that's the issue.

There is something close to my question here: How to Cache InputStream for Multiple Use

Is there a way to improve that solution and provide something that we can use?

Community
  • 1
  • 1
Waza_Be
  • 39,407
  • 49
  • 186
  • 260

2 Answers2

31

I would probably drain the input stream into a byte[] using ByteArrayOutputStream and then create a new ByteArrayInputStream based on the result every time I need to reread the stream.

Something like this:

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 ...

Related, and possibly useful, questions and answers:

Community
  • 1
  • 1
aioobe
  • 413,195
  • 112
  • 811
  • 826
0

Alternatively, I found this great way to achieve it:

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());
    }
}

And I call it with

CopyInputStream cis = new CopyInputStream(input);
InputStream input1 = cis.getCopy();
Waza_Be
  • 39,407
  • 49
  • 186
  • 260