HttpURLConnection读取InputStream两次

时间:2012-09-18 08:34:03

标签: java android inputstream httpurlconnection

我通过HttpURLConnection向服务器发出http get请求,我需要读取响应(InputStream)两次:用于记录和解析响应。返回的InputStraemorg.apache.harmony.luni.internal.net.www.protocol.http.ChunkedInputStream的实例,不支持标记(is.markSupported()返回false)。

因此我不能mark()reset()流,并且在日志中写入响应后我无法解析它。当然,我可以将响应读入String或其他内容,记录它们,然后解析。但是当我正在使用流时,我正在避免潜在的OutOfMemomryError因为流处理缓冲而不是我。

在这种情况下,最佳解决方案是什么,它将保持使用流的好处并帮助实现所需的结果:同时记录到日志和解析响应?

编辑:将回复写入临时文件的解决方案不合适

3 个答案:

答案 0 :(得分:4)

我不确定我是否完全理解,你想阅读InputStream一次(不是真的两次,有点不洁净的IMO,因为如果只在日志流而不是流上发生错误怎么办?你正在解析吗?)然后只需记录并解析相同的InputStream

如果以上是这种情况,则伪显示解决方案:

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

对于同时记录和记录更好的是为两个方法创建一个新的Thread / Runnable,启动它们并等待它们返回(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();
    }
}

答案 1 :(得分:2)

您永远不需要两次读取输入流。在阅读时记录它。

答案 2 :(得分:0)

如果您事先并不知道流的潜在大小(或者如果它太大而无法放入Stringbyte[]),那么我会使用{{1要记录的InputStream(如果需要,可能在一个单独的文件中),我会使用日志文件进行解析。

这可能不是复制HttpURLConnection最有效的方法,但可能是最安全的记忆之一。