InputStream的available()倾向于停止

时间:2012-05-22 02:19:03

标签: java sockets io

这是一个模糊不清的问题,只有当我在某些计算机上时才会发生。 我今天在我们学校的XP电脑上遇到这个问题,我似乎无法在家用电脑上复制这个问题(W7)。

无论如何,每当我使用这段代码时,读取/写入Java中的套接字都会出现问题(其中:int avail, InputStream socket, byte[] buffer, String output):

                   while( (avail = input.available()) > 0 )
                    {
                        read = input.read( buffer );
                        output += new String( buffer, 0, read );
                    }

它似乎有意义(读取所有数据,直到没有数据可用于临时缓冲区,然后到字符串),但在我们学校的计算机上(使用IE7测试它),整个事情以某种方式暂停。我认为input.available()导致它以某种方式阻塞,因为线程只是在没有到达端点的情况下保持运行...实际上只是暂停某个地方。

OH,我忘了提及:每当我在调试模式下运行它并逐步执行每一行时,它的工作方式完全像它应该......这让我更加困惑。

当我回到家中复制这个问题时,它运行得很好(只使用Firefox和IE8)。我不知道什么是更好的替代方案。

PS: 如果缓冲区足够大,我只使用:

                    read = input.read( buffer );
                    output += new String( buffer, 0, read );

它工作得很好,但总是担心发送的数据会超过缓冲区大小。

3 个答案:

答案 0 :(得分:3)

你正在考虑available()错误的方式。该方法tells you approximately how many bytes can be read right now,没有阻止。你正在尝试做的普遍接受的习语是

int length;
while ((length = in.read(buffer)) != -1) {
    output += new String(buffer, 0, length);
}

或沿着这些方向的东西(未编译/测试)。

更新:我认为你误解了“流的结束”的概念。 “流的结尾”并不意味着您已阅读的所有数据都已被读取。这意味着没有,也永远不会有任何其他东西要阅读。例如,它可能意味着您正在读取文件并且已经结束它,或者它可能意味着您正在读取内存中的字节数组并且结束了。那些是“溪流的终结”。

在您的问题中,您表示或至少暗示您是reading from a Socket。您是否意识到在相关的Socket或连接的远程端关闭之前,您永远不会到达该流的末尾?仅仅因为你从它那里收到了一些数据并没有使它成为流的末尾。

答案 1 :(得分:1)

为什么不使用缓冲读卡器?类似的东西:

    BufferedReader reader = new BufferedReader(new InputStreamReader(input));
    String output = "";
    try {
        String readLine = null;
        while ((readLine = reader.readLine()) != null) {
            output += readLine + "\n";
        }
    } catch (IOException e) {
        System.err.println("Error: " + e);
    }
    System.out.println("Read from Socket:" + output);

答案 2 :(得分:1)

您的代码无效。这是对available()的误用。它所做的只是告诉你可以在没有阻塞的情况下读取多少字节。它不能用于指示对等体将发送多少字节,并且它与对等消息没有必要的关系。 TCP中没有消息,只有字节流。如果要读取EOS,只需删除available()测试并读取直到它返回-1。如果你想阅读一条消息,对等体必须以某种方式为你划分它,例如通过带外终结符,长度字前缀或自描述协议(如对象序列化或XML)。

它在调试模式下“有效”,因为您通过断点彻底改变了时序。这进一步证明了你所做的不正确。