我通过HttpURLConnection
向服务器发出http get请求,我需要读取响应(InputStream
)两次:用于记录和解析响应。返回的InputStraem
是org.apache.harmony.luni.internal.net.www.protocol.http.ChunkedInputStream
的实例,不支持标记(is.markSupported()
返回false
)。
因此我不能mark()
和reset()
流,并且在日志中写入响应后我无法解析它。当然,我可以将响应读入String
或其他内容,记录它们,然后解析。但是当我正在使用流时,我正在避免潜在的OutOfMemomryError
因为流处理缓冲而不是我。
在这种情况下,最佳解决方案是什么,它将保持使用流的好处并帮助实现所需的结果:同时记录到日志和解析响应?
编辑:将回复写入临时文件的解决方案不合适
答案 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)
如果您事先并不知道流的潜在大小(或者如果它太大而无法放入String
或byte[]
),那么我会使用{{1要记录的InputStream
(如果需要,可能在一个单独的文件中),我会使用日志文件进行解析。
这可能不是复制HttpURLConnection
最有效的方法,但可能是最安全的记忆之一。