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, но, вероятно, один из самых безопасных способов запоминания.