Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java BufferedReader.readLine()有时会挂起_Java_Apache_Rss_Httpclient_Bufferedreader - Fatal编程技术网

Java BufferedReader.readLine()有时会挂起

Java BufferedReader.readLine()有时会挂起,java,apache,rss,httpclient,bufferedreader,Java,Apache,Rss,Httpclient,Bufferedreader,在我的应用程序中,有一个单独的线程,每分钟由ScheduledExecutorService.scheduleAtFixedRate()运行,它解析来自多个网站的rss提要。我正在使用ApacheHttpClient来接收xml 示例代码: InputStream inputStream = HTTPClient.get(url); String xml = inputStreamToString(inputStream, encoding, websiteName); public

在我的应用程序中,有一个单独的线程,每分钟由ScheduledExecutorService.scheduleAtFixedRate()运行,它解析来自多个网站的rss提要。我正在使用ApacheHttpClient来接收xml

示例代码:

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.ready()
中返回
false
,但是它们解析得很好

如何防止线程挂起在bufferedReader.readLine()上

如果重要的话,
response.getStatusLine().toString()
总是返回
HTTP/1.1200 OK

编辑

我刚刚发现当挂起发生时,
bufferedReader.ready()
实际上是
true

编辑2

BufferedReader.read()
也会挂起。奇怪的是,挂起只发生在处理一个单一的网站,它的发生是绝对随机的。应用程序可以工作15个小时,收到数百个无问题的响应,或者在启动后10分钟内挂起。我已经开始将每个更新的所有字符写入单独的文件,并发现没有什么特别的事情发生。XML读取只是在文档中间永久停止,最后的字符是“代码> P dir=“LTR”和G < /代码>。更新了代码

另外,值得一提的是,不可能有任何未处理的异常,因为在我的
ScheduledExecutorService.scheduleAtFixedRate()的最高级别上,我可以捕获
Throwable
,并打印它的stackTrace。

ready()
方法返回
true
告诉您有可读取的字符。问题是
readLine()
阻塞,直到它在输入中找到行的结尾

公共字符串读取行() 抛出IOException

读一行文字。一条线路被视为由任何一条线路终止 换行符('\n')、回车符('\r')或回车符的 紧接着是换行符

当您从流中读取数据时,无法保证数据将从行边界进入,因此
readLine()
调用将阻塞

您可以使用不会阻塞的
read
方法,但您必须自己检查EOL

公共整数读取(char[]cbuf,int off,int len)引发IOException

将字符读入数组的一部分

此方法实现了对应读取的总合同 Reader类的方法。作为额外的便利,它尝试 通过反复调用read命令读取尽可能多的字符 基础流的方法。此迭代读取将持续到 下列条件之一变为真:

The specified number of characters have been read,
The read method of the underlying stream returns -1, indicating end-of-file, or
The ready method of the underlying stream returns false, indicating that further input requests would block. 
如果基础流上的第一次读取返回-1,则表示 文件结尾,然后此方法返回-1。否则,此方法返回 实际读取的字符数


此外,您还必须根据读取的字符重建行。一次读取整行内容并不方便,但必须这样做。

编码有问题吗?所以
readLine()
无法识别EOL。@我不这么认为。EOL是标准的。如果readLine无法识别EOL,它将永远保持读取,并且您将遇到更大的问题,因为line变量将占用大量内存,并且字符串中以垃圾结尾。将代码更改为
,而((letter=bufferedReader.read())!=-1)
,看起来它现在工作正常。谢天谢地,我真的不需要把线分开。天哪,它还是会不时冻结。有时看起来像是
bufferedReader.read()
从不等于
-1
。可能是什么情况?@DaSH你能发布你的更新代码吗-1应该表示EOF,但由于您不是从实际文件读取EOF,因此EOF的含义有所不同。至少你应该得到一个例外。它会永远被阻塞还是在一段时间后继续?