将InputStream包装到非阻塞的ReadableByteChannel

时间:2014-10-07 07:33:32

标签: java nio

是否可以从InputStream对象创建非阻塞的ReadableByteChannel?

Channel.newChannel(inputStream) - 生成可被阻塞的InputStream.read调用阻止的通道

3 个答案:

答案 0 :(得分:1)

您可以尝试使用' Inputstream.avalable()'来自己实施此类频道。避免阻塞。但是,此方法不保证返回正确的值,因此您必须检查您使用的Inputstream实现。

您确定需要非阻塞频道吗?通常,它需要定期轮询以检查数据的到达。在数据到达时调用回调的异步通道更有意义。

答案 1 :(得分:1)

不,不可能。请参阅Javadoc

答案 2 :(得分:0)

ReadableByteChannel.newChannel方法

public static ReadableByteChannel newChannel(final InputStream in) {
    checkNotNull(in, "in");

    if (in instanceof FileInputStream &&
        FileInputStream.class.equals(in.getClass())) {
        return ((FileInputStream)in).getChannel();
    }

    return new ReadableByteChannelImpl(in);
}

和ReadableByteChannelImpl的读取方法

public int read(ByteBuffer dst) throws IOException {
    int len = dst.remaining();
    int totalRead = 0;
    int bytesRead = 0;
    synchronized (readLock) {
        while (totalRead < len) {
            int bytesToRead = Math.min((len - totalRead),
                                       TRANSFER_SIZE);
            if (buf.length < bytesToRead)
                buf = new byte[bytesToRead];
            if ((totalRead > 0) && !(in.available() > 0))
                break; // block at most once
            try {
                begin();
                bytesRead = in.read(buf, 0, bytesToRead);
            } finally {
                end(bytesRead > 0);
            }
            if (bytesRead < 0)
                break;
            else
                totalRead += bytesRead;
            dst.put(buf, 0, bytesRead);
        }
        if ((bytesRead < 0) && (totalRead == 0))
            return -1;

        return totalRead;
    }
}

所以,它只是调用InputStream的read方法,以及Inputstream的read方法的javadoc:

  

此方法将阻塞,直到输入数据可用,文件结尾为   检测到,或抛出异常。

所以你可以实现InputStream的子类并覆盖read方法,并将这些方法实现为非阻塞。