在我的应用程序中,有一个单独的线程,每分钟运行ScheduledExecutorService.scheduleAtFixedRate()
,它解析来自多个网站的rss提要。我使用Apache HttpClient来接收XML。BufferedReader.readLine()有时会挂起
示例代码:
InputStream inputStream = HTTPClient.get(url);
String xml = inputStreamToString(inputStream, encoding, websiteName);
public static String inputStreamToString(InputStream inputStream, String encoding, String websiteName)
{
BufferedReader bufferedReader = null;
PrintWriter printWriter = null;
StringBuilder stringBuilder = new StringBuilder();
int letter;
try
{
bufferedReader = new BufferedReader(new InputStreamReader(inputStream, encoding));
printWriter = new PrintWriter(new File("src/doclog/"
+ websiteName + "_"
+ new SimpleDateFormat("MM_dd_yyyy_hh_mm_ss").format(new Date(System.currentTimeMillis()))
+ "_" + encoding + ".txt"), encoding);
while((letter = bufferedReader.read()) != -1)
{
char character = (char) letter;
printWriter.print(character);
stringBuilder.append(character);
}
}
catch(IOException e)
{
throw new RuntimeException(e);
}
finally
{
try
{
if(bufferedReader != null)
{
bufferedReader.close();
}
if(printWriter != null)
{
printWriter.close();
}
}
catch(IOException e)
{
e.printStackTrace();
}
}
System.out.println("String built");
return stringBuilder.toString();
}
而且类的HTTPClient:
public class HTTPClient
{
private static final HttpClient CLIENT = HttpClientBuilder.create().build();
public static InputStream get(String url)
{
try
{
HttpGet request = new HttpGet(url);
HttpResponse response = CLIENT.execute(request);
System.out.println("Response Code: " + response.getStatusLine().toString());
return response.getEntity().getContent();
}
catch(IOException | IllegalArgumentException e)
{
throw new RuntimeException(e);
}
}
}
正如标题所说,有时是一个机会,bufferedReader.readLine()
将永远挂起。我已经看到有关此主题的其他答案,并且他们建议检查bufferedReader.ready()
是否返回true
。问题是有些网站在处理它们时总是返回,但是它们解析得很好。
如何防止我的线程挂在bufferedReader.readLine()上?
如果它的事项,response.getStatusLine().toString()
总是返回HTTP/1.1 200 OK
编辑
我刚刚发现bufferedReader.ready()
实际上是true
挂时发生。
编辑2
BufferedReader.read()
挂起为好。奇怪的是,挂起只发生在一个单一的网站上时,它的发生是绝对随机的。应用程序可以工作15个小时,接收数百个无问题的响应,或者在启动后10分钟内挂起。我已经开始将每个更新的所有字符写入单独的文件,并发现没有什么特别的事情发生。 Xml阅读只是在文档中间永远停止,最后的字符是<p dir="ltr"&g
。更新了代码。
另外值得一提的是,不能有任何未处理的异常,因为在我的ScheduledExecutorService.scheduleAtFixedRate()
可运行的最高级别上,我捕获了Throwable
,并打印出它的stackTrace。
难道是编码问题吗?所以'readLine()'不能识别EOL。 – DaSH
@DaSH我不这么认为。 EOL是标准的。如果readLine没有识别EOL,它会一直读取,并且你会遇到更大的问题,因为行变量会使用大量内存,并且会以字符串中的垃圾结束。 – whbogado
将代码更改为'while((letter = bufferedReader.read())!= -1)',看起来好像现在工作正常。谢天谢地,我不需要分开线路。 – DaSH