wffweb/src/main/java/com/webfirmframework/wffweb/util/ByteBufferUtil.java
public static int slice(final ByteBuffer data, final int maxSliceSize,
            final Slice<ByteBuffer> slice) {

        ByteBuffer d = data;

        int remaining = 0;
        int sliceCount = 0;
        while ((remaining = d.remaining()) > 0) {
            sliceCount++;
            final byte[] bytes = new byte[maxSliceSize < remaining
                    ? maxSliceSize
                    : remaining];

            final boolean goOn = slice.each(ByteBuffer.wrap(bytes),
                    d.get(bytes).remaining() == 0);

            if (!goOn) {
                break;
            }

            d = d.slice();
        }

        return sliceCount;
    }
public static int slice(final ByteBuffer data, final int maxSliceSize,
            final Slice<ByteBuffer> slice) {

        ByteBuffer d = data;

        int remaining = 0;
        int sliceCount = 0;
        while ((remaining = d.remaining()) > 0) {
            sliceCount++;
            final byte[] bytes = new byte[maxSliceSize < remaining
                    ? maxSliceSize
                    : remaining];

            final boolean goOn = slice.each(ByteBuffer.wrap(bytes),
                    d.get(bytes).remaining() == 0);

            if (!goOn) {
                break;
            }

            d = d.slice();
        }

        return sliceCount;
    }
Eg:

<pre>
<code>
final String s = "1234567890abc";
final ByteBuffer inputData = ByteBuffer
.wrap(s.getBytes(StandardCharsets.UTF_8));

final StringBuilder builder = new StringBuilder();

final int totalSlices = ByteBufferUtil.slice(inputData, 3,
(part, last) -&gt; {
builder.append(
new String(part.array(), StandardCharsets.UTF_8));
return !last;
});

System.out.println(s.equals(builder.toString()));
System.out.println(5 == totalSlices);
</code>
</pre>

prints

<pre>
true
true
</pre>

@param data
ByteBuffer to be sliced
@param maxSliceSize
the maximum size of ByteBuffer of the sliced
part.
@param slice
the Slice functional interface. The method
Slice.each must return true to continue slicing.
@return the total number of slices made. NB: it is just the count of
invocation of Slice.each method. If the Slice.each returned false
while the last (second param in Slice.each) is false then the
returned slice count will be less than the probable number of
slices in the input data.
@since 3.0.1