InputStream的问题

时间:2012-07-05 19:44:44

标签: java inputstream outputstream

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

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;
    }
}

3 个答案:

答案 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它对我来说很好用!