Thursday, 14 June 2018

ByteBuffer in java

ByteBuffer in java

Byte Buffer is the new Input output package in java.this package is also use for high perfomance
conversions of byte to char data.A byte buffer class defines six categories of operations upon byte buffer.
1.Absolute and relative get and put methods that read and write single bytes;

2.Relative bulk get methods that transfer contiguous sequences of bytes from this buffer into an array;

3.Relative bulk put methods that transfer contiguous sequences of bytes from a byte array or some other byte buffer into this buffer;

4.Absolute and relative get and put methods that read and write values of other primitive types, translating them to and from sequences of bytes in a particular byte order;

5.Methods for creating view buffers, which allow a byte buffer to be viewed as a buffer containing values of some other primitive type; and

6.Methods for compacting, duplicating, and slicing a byte buffer.

how to use ByteBuffer in java

You would expect ByteBuffer to have a length() method, it does not. Instead it has a several length-like concepts:
mark <= position <= limit <= capacity.
Just what do these term mean in English? Working right to left:
capacity

Inside the ByteBuffer, there is a backing byte[] or something that behaves much like one. The capacity is its size. The capacity indexes the first slot past the end of the buffer.
limit

When filling the buffer, the limit is the same as the capacity. When emptying the buffer, it is one past the last filled byte in the buffer.
position

When filling the buffer, the position points just past the last byte filled in the buffer. When emptying the buffer, the position points just past the last byte written from the buffer.
mark

The mark is an optional bookmark to let you record an interesting spot in the ByteBuffer that you want to return to later. When you take a mark() it records current position and when you call reset() it restores that position.

  • Note how you must call ByteBuffer.clear to empty the buffer prior to the physical read.
  • Then you call FileChannel.read to do the physical read.
  • You then must call ByteBuffer.flip to convert from filling the buffer via physical I/O to emptying it via ByteBuffer. get.
  • Then you use ByteBuffer.get to fetch the bytes out of the buffer.
Access to binary data

This class defines methods for reading and writing values of all other primitive types, except boolean. Primitive values are translated to (or from) sequences of bytes according to the buffer's current byte order, which may be retrieved and modified via the order methods. Specific byte orders are represented by instances of the ByteOrder class. The initial order of a byte buffer is always BIG_ENDIAN.

For access to heterogeneous binary data, that is, sequences of values of different types, this class defines a family of absolute and relative get and put methods for each type. For 32-bit floating-point values, for example, this class defines:

 float  getFloat()
 float  getFloat(int index)
  void  putFloat(float f)
  void  putFloat(int index, float f)
Corresponding methods are defined for the types char, short, int, long, and double. The index parameters of the absolute get and put methods are in terms of bytes rather than of the type being read or written.

For access to homogeneous binary data, that is, sequences of values of the same type, this class defines methods that can create views of a given byte buffer. A view buffer is simply another buffer whose content is backed by the byte buffer. Changes to the byte buffer's content will be visible in the view buffer, and vice versa; the two buffers' position, limit, and mark values are independent. The asFloatBuffer method, for example, creates an instance of the FloatBuffer class that is backed by the byte buffer upon which the method is invoked. Corresponding view-creation methods are defined for the types char, short, int, long, and double.

View buffers have three important advantages over the families of type-specific get and put methods described above:

A view buffer is indexed not in terms of bytes but rather in terms of the type-specific size of its values;

A view buffer provides relative bulk get and put methods that can transfer contiguous sequences of values between a buffer and an array or some other buffer of the same type; and

A view buffer is potentially much more efficient because it will be direct if, and only if, its backing byte buffer is direct.

The byte order of a view buffer is fixed to be that of its byte buffer at the time that the view is created.

Invocation chaining

Methods in this class that do not otherwise have a value to return are specified to return the buffer upon which they are invoked. This allows method invocations to be chained. The sequence of statements

 bb.putInt(0xCAFEBABE);
 bb.putShort(3);
 bb.putShort(45);


what problem to use in ByteBuffer in java

The biggest problem in understanding ByteBuffer is presuming that it is cleverer than it really is.
ByteBuffer is a baffling class. It is a bit like a RAM-based RandomAccessFile. It is also a bit like a ByteArrayList without the autogrow feature, to let you deal with partly filled byte[] in a consistent way.
It looks at first as if it might be a traditional circular squirrel cage buffer but it is not. There is no circularity. Nor is it some kind of virtual moving window on a file.
It is not like a pipe, designed to simulate a giant stream with a finite buffer. There is no queuing of any kind.
It is not even as clever as COBOL double buffering, which you might suspect by it having a flip method.
It has no asynchronous look-ahead.
It is extremely low level. nio should probably have been call llio (low level io). You must explicitly clear and fill the buffer and explicitly read/or write it. It is up to you to avoid overfilling the buffer.
It is a very mundane buffer. The only thing that makes it much different from a raw byte[] is the way may be backed something that only looks like a byte[] but is not really, e.g. An entire memory mapped file or direct I/O buffer containg part of a file.

An example of using ByteBuffer


public static void main(String[] args)
    {
     // Create a ByteBuffer using a byte array
     byte[] bytes = new byte[10];
     ByteBuffer buf = ByteBuffer.wrap(bytes);
   
     // Create a non-direct ByteBuffer with a 10 byte capacity
     // The underlying storage is a byte array.
     buf = ByteBuffer.allocate(10);
   
     // Create a direct (memory-mapped) ByteBuffer with a 10 byte capacity.
     buf = ByteBuffer.allocateDirect(10);
   
     // Get the ByteBuffer's capacity
     int capacity = bbuf.capacity(); // 10
   
     // Use the absolute get(). This method does not affect the position.
     byte b = bbuf.get(5); // position=0
   
     // Set the position
     bbuf.position(5);
   
     // Use the relative get()
     b = bbuf.get();
   
     // Get the new position
     int pos = bbuf.position(); // 6
   
     // Get remaining byte count
     int rem = bbuf.remaining(); // 4
   
     // Set the limit
     bbuf.limit(7); // remaining=1
   
     // This convenience method sets the position to 0
     bbuf.rewind(); // remaining=7
   
     // Use the absolute put(). This method does not affect the position.
     bbuf.put((byte)0xFF); // position=0
   
     // Use the relative put()
     bbuf.put((byte)0xFF);
   
     // This convenience method sets the position to 0
     bbuf.rewind(); // remaining=7
   
   
     /*
     Use ByteBuffer to store Strings
     */
     // Create a character ByteBuffer
     CharBuffer cbuf = buf.asCharBuffer();
   
     // Write a string
     cbuf.put("str");
   
     // Convert character ByteBuffer to a string.
     // Uses characters between current position and limit so flip it first
     cbuf.flip();
     String s = cbuf.toString(); // str Does not affect position
   
     // Get a substring
     int start = 2; // start is relative to cbuf's current position
     int end = 5;
     CharSequence sub = cbuf.subSequence(start, end); // str
   
     /*
     Set Byte Ordering for a ByteBuffer
     */
     // Get default byte ordering
     ByteOrder order = buf.order(); // ByteOrder.BIG_ENDIAN
   
     // Put a multibyte value
     buf.putShort(0, (short)123);
     buf.get(0); // 0
     buf.get(1); // 123
   
     // Set to little endian
     buf.order(ByteOrder.LITTLE_ENDIAN);
   
     // Put a multibyte value
     buf.putShort(0, (short)123);
     buf.get(0); // 123
     buf.get(1); // 0
}

}

0 comments:

Post a Comment