2008-12-22 14:35:02softlive

Byte Buffers的幾種作法 II

5.Getting and Setting Non-Byte Java Types in a ByteBuffer
The ByteBuffer class provides convenience methods for getting and putting other multibyte Java primitive types. There are two issues to be aware of when using these methods. First, ensure that values will be stored using the desired byte ordering;  Second, the hasRemaining() method cannot be used to determine if the buffer has room for a multibyte put.

ByteBuffer buf = ByteBuffer.allocate(100);
   
    // Put values of different types
    buf.putChar((char)123);
    buf.putShort((short)123);
    buf.putInt(123);
    buf.putLong(123L);
    buf.putFloat(12.3F);
    buf.putDouble(12.3D);
   
    // Reset position for reading
    buf.flip();
   
    // Retrieve the values
    char c = buf.getChar();
    short s = buf.getShort();
    int i = buf.getInt();
    long l = buf.getLong();
    float f = buf.getFloat();
    double d = buf.getDouble();

6.Creating a Non-Byte Java Type Buffer on a ByteBuffer
You can create views on a ByteBuffer to support buffers of other Java primitive types. For example, by creating a character view on a ByteBuffer, you treat the ByteBuffer like a buffer of characters. The character buffer supports strings directly. Also, hasRemaining() properly works with characters rather than with bytes.

When you create a typed view, it is important to be aware that it is created on top of the bytes between position and limit. That is, the capacity of the new view is (limit - position). The limit of the new view may be reduced so that the capacity is an integral value based on the size of the type. Finally, the view shares the same storage as the underlying ByteBuffer, so any changes to the byte buffer will be seen by the view and visa versa. However, changes to a view's position or limit do not affect the ByteBuffer's properties and visa versa.

ByteBuffer buf = ByteBuffer.allocate(15);
    // remaining = 15
   
    // Create a character ByteBuffer
    CharBuffer cbuf = buf.asCharBuffer();
    // remaining = 7
   
    // Create a short ByteBuffer
    ShortBuffer sbuf = buf.asShortBuffer();
    // remaining = 7
   
    // Create an integer ByteBuffer
    IntBuffer ibuf = buf.asIntBuffer();
    // remaining = 3
   
    // Create a long ByteBuffer
    LongBuffer lbuf = buf.asLongBuffer();
    // remaining = 1
   
    // Create a float ByteBuffer
    FloatBuffer fbuf = buf.asFloatBuffer();
    // remaining = 3
   
    // Create a double ByteBuffer
    DoubleBuffer dbuf = buf.asDoubleBuffer();
    // remaining = 1

7.Using a ByteBuffer to Store Strings
This example demonstrates how to use a ByteBuffer to store characters. For example, an application may want to store strings in a file to avoid the conversion to and from bytes. The example creates a character view on the ByteBuffer that provides methods for reading and writing strings.

This example does not convert characters and bytes. For an example on how to convert characters to and from bytes,

 ByteBuffer buf = ByteBuffer.allocate(100);
   
    // Create a character ByteBuffer
    CharBuffer cbuf = buf.asCharBuffer();
   
    // Write a string
    cbuf.put("a string");
   
    // Convert character ByteBuffer to a string.
    // Uses characters between current position and limit so flip it first
    cbuf.flip();
    String s = cbuf.toString();  // a string
    // 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

8.Setting the Byte Ordering for a ByteBuffer
By default, the byte ordering for a ByteBuffer is ByteOrder.BIG_ENDIAN. This means that if you put a multibyte value into the buffer, the most significant byte is written out first. With LITTLE_ENDIAN, the least significant byte is written out first.

ByteBuffer buf = ByteBuffer.allocate(10);
   
    // 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