HttpURLConnection считывает InputStream дважды
Я делаю запрос HTTP get к серверу через HttpURLConnection
, и мне нужно прочитать ответ (InputStream
) дважды: для регистрации и для разбора ответа. Возвращаемый InputStraem
является экземпляром org.apache.harmony.luni.internal.net.www.protocol.http.ChunkedInputStream
, который не поддерживает маркировку (is.markSupported()
return false
).
Поэтому я не могу mark()
и reset()
потоком и после записи ответа в журнал я не могу его разобрать. Конечно, я могу прочитать ответ один раз в String
или что-то еще, записать их и позже проанализировать. Но когда я работаю с потоками, я избегаю потенциально OutOfMemomryError
, поскольку потоки сделок с буферизации вместо меня.
Какое лучшее решение в данном случае сохранит преимущества использования потоков и поможет достичь желаемого результата: одновременной записи в лог и разбора ответа?
EDIT: решение с записью ответа во временный файл не подходит
3 ответа:
Я не уверен, что полностью понимаю, что вы хотели бы прочитать
InputStream
один раз (не совсем дважды, это немного нечисто ИМО, потому что что делать, если ошибка возникает только в потоке журнала, а не в потоке, который вы анализируете?) а потом просто войти и разобрать то же самое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(); } }
Если вы заранее не знаете потенциальный размер потока (или если он слишком велик, чтобы быть помещенным в
String
илиbyte[]
), то я бы использовалInputStream
изHttpURLConnection
для ведения журнала (возможно, в отдельном файле, если вам нужно), и я бы использовал файл журнала для целей синтаксического анализа.Это, вероятно, не самый эффективный способ дублирования
InputStream
, но, вероятно, один из самых безопасных способов запоминания.