4

The Java API documentation for ByteBuffer.arrayOffset states:

Returns the offset within this buffer's backing array of the first element of the buffer (optional operation).

I cannot figure out how to get arrayOffset() to return a non-zero value. Does anyone know how to change the result of a call to the ByteBuffer.arrayOffset() method?

1
  • 1
    can you show us your code? what kind of error you get? Commented Jul 6, 2014 at 23:05

5 Answers 5

5

Updated to describe the use of slice on array backed ByteBuffer.

The array offset points to an offset in a backing buffer. One of the ways to get a value other than 0 is to create an array backed ByteBuffer, then call slice. The result of slice will have an offset value corresponding to the current position of the original ByteBuffer. The array offset is only useful when getting the backing array to interact with directly

Sign up to request clarification or add additional context in comments.

2 Comments

This is simply not true, which is easy to check.
This answer has been modified since the comment from @LubosD, and now contains factually accurate information. +1.
2

I assume that you are using this (or similar) documentation: http://docs.oracle.com/javase/7/docs/api/java/nio/ByteBuffer.html

I have just experimented with this and it appears that the offset really is always zero for the base class:

  java.nio.ByteBuffer bb = java.nio.ByteBuffer.wrap("The dog chased the cat".getBytes());
  System.out.println("offset test: " + bb.arrayOffset());
  bb.putChar(5, 'Z');
  System.out.println("offset test: " + bb.arrayOffset());
  bb.getChar(5);
  System.out.println("offset test: " + bb.arrayOffset());

Note that java.nio.ByteBuffer is an abstract class, and I used the static wrap method to create an instance of the class java.nio.HeapByteBuffer (documentation is here http://www.docjar.org/docs/api/java/nio/HeapByteBuffer.html)

The documentation for ByteBuffer says that the implementation of arrayOffset is optional, and the default for non-implementors might always be zero.

When in doubt, get the source code for the Java standard libraries to browse in an IDE like IntelliJ or Eclipse.

Comments

1
public ByteBuffer slice() {
    return new HeapByteBuffer(hb,
                              -1,
                              0,
                              this.remaining(),
                              this.remaining(),
                              this.position() + offset);
}


ByteBuffer byteBuffer = ByteBuffer.allocate(32);
byteBuffer.putChar('A');
ByteBuffer sliceByteBuffer = byteBuffer.slice();
print("arrayOffset = "+ sliceByteBuffer.arrayOffset());//arrayOffset = 2

1 Comment

While this code may answer the question, providing information on how and why it solves the problem improves its long-term value
0

ByteBuffer.wrap() returns a HeapByteBuffer by calling its constructor:

HeapByteBuffer(byte[] buf, int off, int len) { // package-private

    super(-1, off, off + len, buf.length, buf, 0);
    /*
    hb = buf;
    offset = 0;
    */
}

the last param of super() is what arrayOffset() returrns. So, always zero!

1 Comment

Downvoted due to the fact that this answer assumes ByteBuffer.wrap is the only method that calls the HeapByteBuffer constructor. By inspecting the source code of the HeapByteBuffer class, it can be verified that the slice() method changes the value returned by the arrayOffset() method.
0

The arrayOffset is apparently used by the ByteBuffer when it calculates an index into the background array of bytes when a put or get method is called. It may always be zero on arrays assigned on the heap (wrapped array). This is not always true for some implementations of allocateDirect().

On the Zebra Android MC33 the implementation of ByteBuffer using an allocateDirect() can have a non-zero offset. For example, a return value of 4 from the arrayOffset() method means that a put to position(0) is really updating the 5th byte in the direct array. The top 4 bytes of the array are not being accessed, but are internally part of the background array and are returned when the array() method is called.

When working with classes like FileOutputStream and passing a ByteBuffer array(), the value returned by the arrayOffset() method is necessary to exclude the bytes not used from the real data.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.