简体   繁体   English

使用InputStreamReader和BufferedReader读取HTTP响应的速度很慢?

[英]Slow reading of HTTP response using InputStreamReader and BufferedReader?

I have the following code in Java that sends an HTTP request to a web server and read the response: 我在Java中有以下代码,该代码将HTTP请求发送到Web服务器并读取响应:

StringBuilder response = new StringBuilder(50000);
URL url2 = new URL(ServiceURL); 
connection = (HttpURLConnection)url2.openConnection();
connection.setRequestMethod("POST");

//... (some more connection settings) ...

BufferedWriter  wr = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream(), "UTF-8"));

wr.write(Request);
wr.flush ();
wr.close ();

InputStream is = connection.getInputStream();       
BufferedReader rd = new BufferedReader(new InputStreamReader(is));

int i = 0;
while ((i = rd.read()) > 0) {
    response.append((char)i);
}

It works for most cases, but I have a problem with one server that returns a rather large XML (something like 500KB; I guess this is pretty large for just a bunch of text..), where I keep getting a read timeout exception. 它适用于大多数情况,但是我遇到一个服务器返回一个相当大的XML(大约500KB;我想这对于一堆文本来说是相当大的..)的问题,在此我不断收到读取超时异常。

I believe it's not a network problem, because I've tried making the same request using curl and the response just arrived all right and pretty quick, something like two seconds. 我认为这不是网络问题,因为我尝试使用curl发出相同的请求,并且响应很快就可以正确地到达,大约需要两秒钟。

When I look what's going on in the network (using wireshark to capture the packets), I noticed that the TCP receive window in my computer gets full at some point. 当我查看网络中发生的事情(使用Wireshark捕获数据包)时,我注意到计算机中的TCP接收窗口有时已满。 The TCP stack sometimes survives this; TCP堆栈有时可以幸免于此。 I can see the server sending TCP keep-alive to keep the connection up, but in the end the TCP connection just breaks down. 我可以看到服务器发送TCP保持活动状态以保持连接状态,但最终TCP连接断开了。

Could it be that the reading part of the code (appending the received response character-by-character) is slowing my code down? 可能是代码的读取部分(逐个字符附加接收到的响应)使我的代码变慢了吗? Is there a more efficient way to read an HTTP response? 有没有更有效的方式来读取HTTP响应?

Reading character by character is quite slow, yes. 是的,逐个字符阅读非常慢。 Try reading chunks at a time into a buffer: 尝试一次将大块读取到缓冲区中:

char[] buf = new char[2048];
int charsRead;
while((charsRead = rd.read(buf, 0, 2048)) > 0) {
    response.append(buf, 0, charsRead);
}

As Phil already said reading the stream byte by byte is kinda slow. 正如Phil所说,逐字节读取流有点慢。 I prefer using the readLine() method of BufferedReader : 我更喜欢使用BufferedReader的readLine()方法:

StringBuilder response = new StringBuilder();
String line = "";
while((line = rd.readLine()) != null) {
    response.append(line + System.getProperty("line.separator");
}

If possible, I would consider using the Apache HTTP Client library. 如果可能的话,我会考虑使用Apache HTTP Client库。 It is easy to use and very powerful in handling HTTP stuff. 它易于使用,并且在处理HTTP内容方面非常强大。 http://hc.apache.org/httpcomponents-client-ga/ http://hc.apache.org/httpcomponents-client-ga/

You should also keep in mind to set the socket and connection timeouts. 您还应该记住设置套接字和连接超时。 This way you can control how long a connection is kept open (alt least on you side of the connection). 这样,您可以控制连接保持打开状态的时间(至少在您这边)。

And last but not least always close your HTTP connections in a finally block after you received the response, otherwise you may run into a too many open files problem. 最后但并非最不重要的一点是,在收到响应后,始终在finally块中关闭HTTP连接,否则可能会遇到太多打开文件的问题。

Hope this heps ;) 希望这会麻木;)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM