我想从(Tomcat servlet)的InputStream中读取数据,并使用AsynchronousFileChannel异步地将(大量)内容复制到文件中。 我可以使用常规FileChannel进行操作,如此处所述,并且了解关于缺失的transferTo的信息。 但是,如果我使用Java 7的AsyncFileChannel,则始终会出现BufferOverflowException。
try (AsynchronousFileChannel output = AsynchronousFileChannel.open(path, StandardOpenOption.CREATE, StandardOpenOption.WRITE);
output.lock(); // need to lock, this is one key reason to use channel
ReadableByteChannel input = Channels.newChannel(inputStream); // servlet InputStream
ByteBuffer buf = ByteBuffer.allocate(4096);
int position = 0;
int count;
Future<Integer> lastWrite = null;
while ((count = input.read(buf)) >= 0 || buf.position() > 0) {
logger.info("read {} bytes", count);
buf.flip();
output.write(buf, position);
if (count > 0) position += count;
buf.compact();
}
if (lastWrite != null) lastWrite.get(10, TimeUnit.SECONDS);
然后当我运行时,就会出现以下情况:
14:12:30.597 [http-bio-9090-exec-3] INFO c.b.p.c.BlobUploadServlet - read 4096 bytes
14:12:30.597 [http-bio-9090-exec-3] INFO c.b.p.c.BlobUploadServlet - read 0 bytes
... many more with 0 bytes read ...
14:12:30.597 [http-bio-9090-exec-3] INFO c.b.p.c.BlobUploadServlet - read 3253 bytes
14:12:30.605 [http-bio-9090-exec-3] ERROR c.b.p.c.BlobUploadServlet - null
java.nio.BufferOverflowException: null
at java.nio.HeapByteBuffer.put(HeapByteBuffer.java:183) ~[na:1.7.0_17]
at java.nio.channels.Channels$ReadableByteChannelImpl.read(Channels.java:393) ~[na:1.7.0_17]
我该如何修复缓冲区溢出?另外,当读取0字节时,暂停循环并等待的适当方法是什么?
inputStream
?错误是由于调用了HeapByteBuffer.put
,并传入了一个太大的字节数组,导致无法容纳,但是Channels.ReadableByteChannel.read
似乎是正确的,除非inputStream.read
返回的大小超过了传递给它的最大值。 (那将是InputStream
的错误实现,但是HeapByteBuffer
和ReadableByteChannel
的源代码似乎是正确的。) - Cel Skeggs