2

以下是我将用于我的项目的代码片段的一部分。

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 循环中设置了一个指针(调试),并不断地监视 StringBuffer 被一个一个地填充 char 值。但是突然在检查while循环内的条件时,调试控制丢失了,这就是代码进入挂断状态的地方!也不例外!

这里发生了什么?

编辑::

这就是我获取 InputStream 的方式。基本上我使用 Apache Commons Net 进行 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;
    }
}
4

3 回答 3

5

查看JavaDocs

Reads the next byte of data from the input stream. The value byte is returned as an int in the range 0 to 255. If no byte is available because the end of the stream has been reached, the value -1 is returned. This method blocks until input data is available, the end of the stream is detected, or an exception is thrown.

In simple turns: if your stream ended (e.g. end of file), read() returns -1 immediately. However if the stream is still open but JVM is waiting for data (slow disk, socket connection), read() will block (not really hung).

Where are you getting the stream from? Check out the available() - but please do not call it in a loop exhausting CPU.

Finally: casting int/byte to char will only work for ASCII characters, consider using Reader on top of InputStream.

于 2012-07-05T19:48:29.330 回答
2

阅读文档

如果 InputStream 没有关闭,read() 将一直​​等到 InputStream 上有更多数据。

我怀疑你是用套接字做这个的吗?这是出现这种情况的最常见区域。

"从输入流中读取数据的下一个字节。值字节以 int 形式返回,范围为 0 到 255。如果由于到达流的末尾而没有可用的字节,则返回值 -1。这方法阻塞,直到输入数据可用、检测到流结束或抛出异常”

于 2012-07-05T19:47:28.877 回答
0

I have the same issue with the Apache Commons on Android ... the read() command on the inputstream hangs forever for some reason. And no, it is not just blocking "until data is available" ... my debugging information shows that there are several 100 chars available() ... yet it just randomly blocks at some read. However, whenever I send something to the telnet server the block is suddenly released and it will continue reading for several chars until it suddenly stops/blocks again at some arbitrary point!

I believe there is some bug within the Apache Commons library! This is really annoying because there isn't a lot that can be done ... no timeout for the read command or anything else ...

EDIT: I was able to get around it ... by setting the TelNetClient.setReaderThread(false) ... obviously there is a bug within the Library that exists as long as a thread handles the input data ... when dispabled it works just fine for me!

于 2012-07-18T14:04:56.690 回答