我有一个包含大文件(100MB)的ByteBuffer:
java.nio.ByteBuffer byteBuffer = ByteBuffer.wrap(multipartFile.getBytes());
writeChannel.write(byteBuffer);
writeChannel.closeFinally();我一次只能合法地向writeChannel写入1MB。
如何对ByteBuffer的内容进行切片并一次仅向writeChannel写入1 MB的切片
发布于 2011-07-05 07:03:18
您可以使用ByteBuffer#slice()获得基本ByteBuffer实例的副本视图,然后移动位置以显示内容的滑动窗口。或者,如果您不需要将基本缓冲区公开给任何其他使用者,您也可以对它执行相同的操作。
您可以通过the single-argument Buffer#position(int) method更改内容视图的起始位置,也可以通过Buffer#limit(int)更改视图的结束位置。只要您注意不要将视图推到超出底层缓冲区的限制,您就可以执行以下操作:
final ByteBuffer view = base.slice();
for (int start = base.position(), end = base.limit(), stride = 1000000;
start != end;
start = view.limit())
consume(view.position(start)
.limit(start + Math.min(end - start, stride)));我没有测试它,但它看起来是正确的。可以重写以避免位置的初始设置,这在这里并不是严格必要的,但它要么会导致一些重复,要么会在第一次出现时出现更尴尬的特殊情况。
我把它留在这里是为了保留基本的for循环结构。
发布于 2011-07-05 06:54:24
据我所知,在writeChannel (我假设它的名称是SocketChannel类型)上的write()将“尝试向通道写入最多r个字节,其中r是调用此方法时缓冲区中剩余的字节数,即dst.remaining()”。(据this报道)
ByteBuffer.remaining()的描述说,此方法将“返回当前位置和限制之间的元素数”。
所以我的猜测不是你不能写整个ByteBuffer,而是你的代码应该在ByteBuffer对象上调用flip(),这样它就变成了:
java.nio.ByteBuffer byteBuffer = ByteBuffer.wrap(multipartFile.getBytes());
byteBuffer.flip();
writeChannel.write(byteBuffer);
writeChannel.closeFinally();正如Buffer.flip()中所说:“在一系列通道读取或put操作之后,调用此方法来准备一系列通道写入或相对get操作。”
https://stackoverflow.com/questions/6576596
复制相似问题