Java网络编程之流--readline()

        早两天生产环境遇到这么一个问题,系统日终跑批任务失败,发现停止在远程读取ftp服务文件任务上,实在搞不定了后来回来让我帮忙分析,我经过分析源代码,发现原来是团队的小伙伴在远程网络连接中使用BufferedReader.readline()引起的。因此及时让团队小伙将业务调整为先从ftp下载文件,再在本地读取文件,避免在网络连接中使用BufferedReader.readline()。

       BufferedReader.readline()方法有一个隐含的bug,它不一定会把一个回车看作行的结束。相反,readline()只识别换行或回车/换行对。当在流中检测到回车时,readline()会在继续之前等待,查看下一个字符是否为换行。如果是换行,就抛掉回车和换行,把这一行作为String返回。如果不是换行,就抛掉回车,把这一行作为String返回,这个额外的字符会作为下一行的一部分读取。但是,如果回车是流的最后一个字符(如果流由Macintosh或者Macintosh创建的文本所生成,就很有可能发生这种情况),那么readline()就会挂起,等待最后一个字符的出现,但这个字符永远也不会出现。

这个问题在读取文件时不太明显,因为肯定会有下一个字符:如果没有别的字符了,那么会由-1表示流结束。但是,在持久的网络连接中(如连接用于FTP和采用最新模型的HTTP),服务器或客户端可能只是在最后一个字符之后停止发送数据,并等待响应,却不会真正关闭连接。如果幸运,连接最终会在一端或另一端超时,你将得到一个IOException异常,虽然这可能会花费至少一两分钟,但这还算是好的。如果不够幸运,程序将永远挂起。

public class ReadLine {

    public static void main(String[] args) {  
        // System.in是标准输入(获取键盘输入的值),  
        // InputStreamReader将字节流转为字符流,将字节流转为BufferedReader  
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));  
        String line;  
        try {  
            // readLine()是阻塞方法,当键盘输入之后,点击回车,得到的值不会为null,就一直处于阻塞状态  
            while ((line = br.readLine()) != null) {  
                System.out.println("dd" + line);  
            }  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
  
    }  
}

 

猜你喜欢

转载自liangjf85-163-com.iteye.com/blog/2392413