以下是我将用于项目的代码段的一部分。
public String fetchFromStream()
{
try
{
int charVal;
StringBuffer sb = new StringBuffer();
while((charVal = inputStream.read()) > 0) {
sb.append((char)charVal);
}
return sb.toString();
} catch (Exception e)
{
m_log.error("readUntil(..) : " + e.getMessage());
return null;
} finally {
System.out.println("<<<<<<<<<<<<<<<<<<<<<< Called >>>>>>>>>>>>>>>>>>>>>>>>>>>");
}
}
最初,while循环开始工作得非常好。但是在从流中读取可能的最后一个字符后,我期望获得-1返回值。但这是我的问题开始的地方。代码被绞死,即使finally块也没有被执行。
我在Eclipse中调试此代码以查看运行时实际发生的情况。我在while循环中设置了一个指针(debug),并且一直在监视StringBuffer,逐个填充char值。但是在检查while循环中的条件时突然,调试控件丢失了,这就是代码进入挂断状态的地方!也没有例外!
这里发生了什么?
编辑::
这就是我获取InputStream的方法。基本上我正在使用Apache Commons Net for Telnet。
private TelnetClient getTelnetSession(String hostname, int port)
{
TelnetClient tc = new TelnetClient();
try
{
tc.connect(hostname, port != 0 ? port : 23);
//These are instance variables
inputStream = tc.getInputStream();
outputStream = new PrintStream(tc.getOutputStream());
//More codes...
return tc;
} catch (SocketException se)
{
m_log.error("getTelnetSession(..) : " + se.getMessage());
return null;
} catch (IOException ioe)
{
m_log.error("getTelnetSession(..) : " + ioe.getMessage());
return null;
} catch (Exception e)
{
m_log.error("getTelnetSession(..) : " + e.getMessage());
return null;
}
}
答案 0 :(得分:5)
查看JavaDocs:
从输入流中读取下一个数据字节。值字节作为int返回,范围为0到255.如果没有字节可用,因为已到达流的端,则返回值-1 。 此方法会阻止输入数据可用,检测到流的末尾,或者抛出异常。
简单转弯:如果你的流结束(例如文件结束),read()
立即返回-1。但是,如果流仍然打开但JVM正在等待数据(慢速磁盘,套接字连接),read()
将阻止(并非真正挂起)。
你从哪里获得流?查看available()
- 但请不要在耗尽CPU的循环中调用它。
最后:将int
/ byte
投射到char
仅适用于ASCII字符,请考虑在Reader
之上使用InputStream
。
答案 1 :(得分:2)
阅读文档
如果InputStream未关闭,read()将一直等到InputStream上有更多数据。
我怀疑你是用套接字做的吗?这是最常见的领域。
“从输入流中读取下一个数据字节。值字节作为int返回,范围为0到255.如果没有字节可用,因为到达了流的末尾,则值为-1返回。此方法将阻塞,直到输入数据可用,检测到流的末尾或抛出异常“
答案 2 :(得分:0)
我对Android上的Apache Commons也有同样的问题... 由于某种原因,输入流上的read()命令永远挂起。不,它不只是阻止“直到数据可用”... 我的调试信息显示有几个100个字符可用()...但它只是在一些读取时随机阻塞。但是,每当我向telnet服务器发送一些东西时,块就会突然释放,并且它将继续读取几个字符,直到它突然停止/在某个任意点再次阻塞!
我相信Apache Commons库中存在一些错误!这真的很烦人,因为没有太多可以做的事情......没有超时的读命令或其他任何东西......
编辑:我能够绕过它...通过设置TelNetClient.setReaderThread(false)...显然只要一个线程处理输入数据,库中就会存在一个bug ...当dispabled它对我来说很好用!