HttpURLConnection reads InputStream twice

I am making an http request to the server through HttpURLConnection , and I need to read the response ( InputStream ) twice: for logging purposes and for parsing response. The returned InputStraem is an instance of org.apache.harmony.luni.internal.net.www.protocol.http.ChunkedInputStream that does not support labeling ( is.markSupported() return false ).

Therefore, I cannot stream mark() and reset() and after writing the response in the log, I cannot parse it. Of course, I can read the answer once in String or something else, write them down and parse later. But when I work with threads, I avoid the potential OutOfMemomryError because threads use buffering instead of me.

What is the best solution in this case will help preserve the advantages of using threads and help achieve the desired result: simultaneous logging and response to parsing?

EDIT: Solution writing response to temporary file not suitable

+4
source share
3 answers

I'm not sure I fully understand, you would like to read an InputStream once (in fact, this is not so dirty IMO, because if the error occurs only in the log stream, and not in the stream you are parsing?), And then just record and parse the same InputStream ?

If the above is the case to show a solution:

 InputStream is=...; byte[] bytes=new byte[1028]; while(is.read(bytes)!=-1) { log(bytes); //call function to log parse(bytes);//call function to parse } 

even better for simultaneously logging and writing will create a new Thread / Runnable for both methods, run them and wait for them to return using ( thread.join(); ):

 InputStream is=...; byte[] bytes=new byte[1028]; while(is.read(bytes)!=-1) { Thread t1=new Thread(new Runnable() { @Override public void run() { log(bytes); //call function to log } }); Thread t2=new Thread(new Runnable() { @Override public void run() { parse(bytes);//call function to parse } }); t1.start(); t2.start(); try { t1.join(); t2.join(); }catch(Exception ex) { ex.printStackTrace(); } } 
+4
source

You will not need to read the input stream twice. Write it down when you read it.

+2
source

If you do not know in advance the potential size of the stream (or if it is too large to be placed in a String or byte[] ), I would use an InputStream for the HttpURLConnection log (perhaps in a separate file if you need), and I would use a file journal for parsing.

This is probably not the most efficient way to duplicate an InputStream , but it is probably one of the most reliable in memory.

0
source

Source: https://habr.com/ru/post/1434788/


All Articles