2012-09-18 69 views
4

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

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

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

编辑:解决方案与写作响应到临时文件是不恰当的

回答

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

我想两次访问完整的流内容(内容是JSON格式的字符串):第一个 - 只是写在日志中,第二个 - 解析反应 –

+1

无论哪种方式,一旦你有JSON格式的字符串传递给*解码*的方法,然后将返回的'String'传递给'log()'和'parse()'。一个Stream是我提到的两次,另一个回答 –

+0

代码有缺陷,它忽略了'read()'的结果,所以它很容易在每个缓冲区结束时处理垃圾。 – EJP

0

如果你事先不知道流的潜在规模(或者如果它是太大而不能放在一个String或一个byte[]),然后我会使用HttpURLConnectionInputStream进行记录(如果需要,可能在一个单独的文件中),我会使用日志文件进行解析。

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

+0

感谢您的回答,但是这个解决方案太慢并且体积太大( –

2

你不应该需要读取的输入流的两倍。在阅读时记录它。