我正在尝试使用while循环从java中的BufferedReader读取行。它将按原样遍历BufferedReader,但是当它应该从循环中断时它将“冻结”代码的执行。我已经尝试调试代码,但循环后执行提示丢失了。不知道我做错了什么:
代码段:
BufferedReader reader = new BufferedReader(new InputStreamReader(yourSocket.getInputStream()));
String nextLine = null;
nextLine = reader.readLine();
while (nextLine != null){ //print all of input stream
System.out.println(nextLine);
nextLine = reader.readLine();
}
我假设当BufferedReader中没有剩下的行时,nextLine变量将返回null并打破循环。我试过手动打破循环,但它似乎也不起作用。同样,代码会打印BufferedReader的行,但是while循环之后的任何代码都不一定会运行。
如果此信息不足,请告知我们。如有必要,我也可以通过完整的代码。
谢谢, 专利
答案 0 :(得分:2)
从套接字读取是一个阻塞调用。您的程序不知道另一方已完成写入套接字的事实。您通常必须使用一些标记或大小信息来识别另一端已完成写入套接字的程序。读完该标记后,您将退出循环。此行为与读取文件不同 - 当您到达文件末尾时,调用readLine()方法时会返回null,并且可以像在示例中一样退出。
答案 1 :(得分:1)
问题出现,因为您的Reader
被一个阻止Socket
所包围,这不会指示流结束直到对等关闭连接(或您的一方关闭连接)。您可能已经阅读了所有 available ,但是当您尝试阅读更多时,基础InputStream
阻止尝试从套接字读取更多数据。
当某些数据最终可用时,InputStream
会将该数据提供给Reader
,并且一旦Reader
看到足以构成完整的行 - 或流结束 - 您将从Reader
退出最后一行。尝试读取下一行最终将返回null。
答案 2 :(得分:0)
我自己编写了一些类似的代码来探索如何在Java中处理HTTP请求,我不相信BufferedReader的行为与从用于传输HTTP请求的Socket读取兼容,因为这里已经提到过,如果没有更多数据要读取,readLine()会阻止,因此您的应用程序会挂起。根据HTTP规范,客户端在写入请求后保持Socket打开,因此readLine()等待直到有更多可用数据。尝试检测HTTP请求的最后一行上的尾随\ n \ r \ n也不会对readLine()返回的行进行处理,因为它会删除任何行尾字符组合:\ n,\ r或\ r \ñ。
请求的标题和正文之间也包含一个空行,因此,如果您要查找空白行作为邮件的终止,则需要检查它是不是该行标题和正文之间。
我认为从InputStream中读取字符并使用read(byte [])是这样做的方法 - 它会读取你的byte []的大小,如果遇到stream的结尾则终止读取。< / p>
答案 3 :(得分:0)
我刚回答了别人的帖子。 My cheater way around this.
像你一样使用循环......
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
sleep(in);
if(!in.ready()){
break;
}
}
我想出了一种骗子的方式。
private static void sleep(BufferedReader in) throws IOException {
long time = System.currentTimeMillis();
while(System.currentTimeMillis()-time < 1000){
if(in.ready()){
break;
}
}
}
这可能很草率,但是如果你做一个等待一段时间的睡眠方法并且只是继续检查BufferedReader是否“准备就绪”。如果是,你可以爆发,但是当你再次出来检查时。 - 也许你可以只返回一个布尔值而不是检查两次,但概念就在那里。