有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

available()/read()上的javasocketInputStream块

我正在阅读Socket InputStream,调用read()和available()可以进行一些循环迭代。以后可以无限期使用()块

可能是什么问题?我怎样才能使它不阻塞

代码:

BufferedInputStream buffIn = new BufferedInputStream(in);
while (true)
{
    if (buffIn.available() > 0)
    {
        len = buffIn.read(buffer, 0, buffer.length);
        if (len == -1)
        {
            break;
        }
        baos.write(buffer, 0, len);
    }
}

共 (2) 个答案

  1. # 1 楼答案

    你的代码有一个相当大的bug;你从来没有用available结果做过任何事;所以你的read

    if (buffIn.available() > 0)
    {
        int amt = (buffIn.available() > buffer.length) ? buffer.length : 
            buffIn.available();
        len = buffIn.read(buffer, 0, amt); // <  see ternary above.
        if (len == -1)
        {
            break;
        }
        baos.write(buffer, 0, len);
    }
    
  2. # 2 楼答案

    available()对于套接字来说不是一个好主意,因为它不能按预期工作。我会在这里使用非阻塞NIO

    SocketChannel sc = ...
    sc.configureBlocking(false);
    ByteBuffer bb = ByteBuffer.allocateDirect(32*1024);
    while(sc.read(bb) > 0) {
        bb.flip();
        while(bb.remaining() > 0 && sc.write(bb) >= 0);
        bb.clear();
    }
    

    这比IO版本的效率要高得多,因为它不会将数据复制到Java scape中,只是为了将其复制回来(它会保存两个副本)

    编辑循环的规范版本如下:

    while (in.read(bb) > 0 || bb.position() > 0)
    {
        bb.flip();
        out.write(bb);
        bb.compact();
    }