Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you get successive slices out of a ByteBuffer?

I have a ByteBuffer that contains a large file (100 MB):

    java.nio.ByteBuffer byteBuffer = ByteBuffer.wrap(multipartFile.getBytes());
    writeChannel.write(byteBuffer);
    writeChannel.closeFinally();

I can only legally write 1 MB to the writeChannel at a time.

How do I slice up the contents of the ByteBuffer and write only a 1 MB slice at a time into the writeChannel?

like image 609
Percy Avatar asked Jul 04 '11 22:07

Percy


People also ask

How do I get data from ByteBuffer?

The get() method of java. nio. ByteBuffer class is used to read the byte at the buffer's current position, and then increments the position. Return Value: This method returns the byte at the buffer's current position.

How do I get strings from ByteBuffer?

The toString() method of ByteBuffer class is the inbuilt method used to returns a string representing the data contained by ByteBuffer Object. A new String object is created and initialized to get the character sequence from this ByteBuffer object and then String is returned by toString().

Which method is used to create a ByteBuffer?

A direct byte buffer may be created by invoking the allocateDirect factory method of this class.

What does ByteBuffer rewind do?

ByteBuffer rewind() methods in Java with Examples ByteBuffer Class is used to rewind this buffer. The position is set to zero and the mark is discarded. Invoke this method before a sequence of channel-write or get operations, assuming that the limit has already been set appropriately.


1 Answers

You can use ByteBuffer#slice() to get a duplicate view of your base ByteBuffer instance, then bump the position along to expose a sliding window of content. Alternately, you can just do the same to your base buffer if you don't need to expose it to any other consumers.

You can change the starting position of your view of the content via the single-argument Buffer#position(int) method, and change the end position of your view via Buffer#limit(int). So long as you're mindful not to push the view beyond the limit of the underlying buffer, you can do the following:

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)));

I didn't test it, but it looks correct. It's possible to rewrite to avoid the initial setting of the position, which isn't strictly necessary here, but it incurs either some repetition or more awkward special case treatment of the first time through.

I left it this way to preserve the basic for loop structure.

like image 78
seh Avatar answered Sep 30 '22 13:09

seh