如何使用CompletionHandlers和小于请求的ByteBuffer读取请求?

时间:2012-05-22 08:50:46

标签: java asynchronous nio bytebuffer completionhandler

我使用的是Java 7和AsynchronousSocketChannel。我想阅读一个请求(例如HTTP POST)但是我很难想出一个很好的解决方案来读取完整的请求,如果它大于ByteBuffer我正在使用的大小。例如。如果ByteBuffer是4048字节且HTTP POST包含的图像大于4kB。

这有什么好的递归解决方案或循环吗?

这是我的阅读请求代码:

public void readRequest(final AsynchronousSocketChannel ch) {
    final ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);
    final StringBuilder strBuilder = new StringBuilder();
    final CharsetDecoder decoder = Charset.forName("US-ASCII").newDecoder();

    ch.read(buffer, null, new CompletionHandler<Integer, Void>() {

        public void completed(Integer bytes, Void att) {

            buffer.flip();                          
            try {
                decoder.reset();
                strBuilder.append(decoder.decode(buffer).toString());
            } catch (CharacterCodingException e) {
                e.printStackTrace();
            }           
            buffer.clear();         

            // More data to read or send response
            if(bytes != -1) {

                // More data to read
                ch.read(...);

            } else {

                // Create and send a response

            }
        }

        public void failed(Throwable exc, Void att) {
            exc.printStackTrace();
        }

    });
}

我写的地方:

// More data to read
ch.read(...);

它看起来像是一个代码重用的好地方,但我无法想出一个很好的解决方案。有什么方法可以在这里重用CompletionHandler吗?有关阅读有限ByteBuffer的完整请求的任何建议吗?

我想以非阻塞和异步的方式解决这个问题。

1 个答案:

答案 0 :(得分:4)

当读取数据块时,从java管理的线程异步调用completed方法。要重用CompletionHandler:

// More data to read
ch.read(buffer, null, this); //here you pass the same CompletionHandler you are using

java小伙伴们建议当你完成读取操作(else块)时,你应该使用另一个线程上下文。

这是一篇文档,旨在避免CompletionHandler内的阻止和长期操作,请参阅第33页http://openjdk.java.net/projects/nio/presentations/TS-4222.pdf