zoukankan      html  css  js  c++  java
  • Java-NIO(二):缓冲区(Buffer)的数据存取

    • 缓冲区(Buffer):

      一个用于特定基本数据类行的容器。有java.nio包定义的,所有缓冲区都是抽象类Buffer的子类。

      Java NIO中的Buffer主要用于与NIO通道进行交互,数据是从通道读入到缓冲区,从缓冲区写入通道中的。

      Buffer就像一个数组,可以保存多个相同类型的数据。根据类型不同(boolean除外),有以下Buffer常用子类:

    1. ByteBuffer
    2. CharBuffer
    3. ShortBuffer
    4. IntBuffer
    5. LongBuffer
    6. FloatBuffer
    7. DoubleBuffer

    上述Buffer类他们都采用相似的方法进行管理数据,只是各自管理的数据类型不同而已,都是通过以下方法获取一个Buffer对象:

    static XxxBuffer allocate(int capacity)

    创建一个容量为capacity的XxxBuffer对象。

    • Buffer中的重要概念:

    1)容量(capacity):表示Buffer最大数据容量,缓冲区容量不能为负,并且建立后不能修改。

    2)限制(limit):第一个不应该读取或者写入的数据的索引,即位于limit后的数据不可以读写。缓冲区的限制不能为负,并且不能大于其容量(capacity)。

    3)位置(position):下一个要读取或写入的数据的索引。缓冲区的位置不能为负,并且不能大于其限制(limit)。

    4)标记(mark)与重置(reset):标记是一个索引,通过Buffer中的mark()方法指定Buffer中一个特定的position,之后可以通过调用reset()方法恢复到这个position。

    java.nio.Buffer.java
      1 /*
      2  * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
      3  * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
      4  *
      5  *
      6  *
      7  *
      8  *
      9  *
     10  *
     11  *
     12  *
     13  *
     14  *
     15  *
     16  *
     17  *
     18  *
     19  *
     20  *
     21  *
     22  *
     23  *
     24  */
     25 
     26 package java.nio;
     27 
     28 import java.util.Spliterator;
     29 
     30 /**
     31  * A container for data of a specific primitive type.
     32  *
     33  * <p> A buffer is a linear, finite sequence of elements of a specific
     34  * primitive type.  Aside from its content, the essential properties of a
     35  * buffer are its capacity, limit, and position: </p>
     36  *
     37  * <blockquote>
     38  *
     39  *   <p> A buffer's <i>capacity</i> is the number of elements it contains.  The
     40  *   capacity of a buffer is never negative and never changes.  </p>
     41  *
     42  *   <p> A buffer's <i>limit</i> is the index of the first element that should
     43  *   not be read or written.  A buffer's limit is never negative and is never
     44  *   greater than its capacity.  </p>
     45  *
     46  *   <p> A buffer's <i>position</i> is the index of the next element to be
     47  *   read or written.  A buffer's position is never negative and is never
     48  *   greater than its limit.  </p>
     49  *
     50  * </blockquote>
     51  *
     52  * <p> There is one subclass of this class for each non-boolean primitive type.
     53  *
     54  *
     55  * <h2> Transferring data </h2>
     56  *
     57  * <p> Each subclass of this class defines two categories of <i>get</i> and
     58  * <i>put</i> operations: </p>
     59  *
     60  * <blockquote>
     61  *
     62  *   <p> <i>Relative</i> operations read or write one or more elements starting
     63  *   at the current position and then increment the position by the number of
     64  *   elements transferred.  If the requested transfer exceeds the limit then a
     65  *   relative <i>get</i> operation throws a {@link BufferUnderflowException}
     66  *   and a relative <i>put</i> operation throws a {@link
     67  *   BufferOverflowException}; in either case, no data is transferred.  </p>
     68  *
     69  *   <p> <i>Absolute</i> operations take an explicit element index and do not
     70  *   affect the position.  Absolute <i>get</i> and <i>put</i> operations throw
     71  *   an {@link IndexOutOfBoundsException} if the index argument exceeds the
     72  *   limit.  </p>
     73  *
     74  * </blockquote>
     75  *
     76  * <p> Data may also, of course, be transferred in to or out of a buffer by the
     77  * I/O operations of an appropriate channel, which are always relative to the
     78  * current position.
     79  *
     80  *
     81  * <h2> Marking and resetting </h2>
     82  *
     83  * <p> A buffer's <i>mark</i> is the index to which its position will be reset
     84  * when the {@link #reset reset} method is invoked.  The mark is not always
     85  * defined, but when it is defined it is never negative and is never greater
     86  * than the position.  If the mark is defined then it is discarded when the
     87  * position or the limit is adjusted to a value smaller than the mark.  If the
     88  * mark is not defined then invoking the {@link #reset reset} method causes an
     89  * {@link InvalidMarkException} to be thrown.
     90  *
     91  *
     92  * <h2> Invariants </h2>
     93  *
     94  * <p> The following invariant holds for the mark, position, limit, and
     95  * capacity values:
     96  *
     97  * <blockquote>
     98  *     <tt>0</tt> <tt>&lt;=</tt>
     99  *     <i>mark</i> <tt>&lt;=</tt>
    100  *     <i>position</i> <tt>&lt;=</tt>
    101  *     <i>limit</i> <tt>&lt;=</tt>
    102  *     <i>capacity</i>
    103  * </blockquote>
    104  *
    105  * <p> A newly-created buffer always has a position of zero and a mark that is
    106  * undefined.  The initial limit may be zero, or it may be some other value
    107  * that depends upon the type of the buffer and the manner in which it is
    108  * constructed.  Each element of a newly-allocated buffer is initialized
    109  * to zero.
    110  *
    111  *
    112  * <h2> Clearing, flipping, and rewinding </h2>
    113  *
    114  * <p> In addition to methods for accessing the position, limit, and capacity
    115  * values and for marking and resetting, this class also defines the following
    116  * operations upon buffers:
    117  *
    118  * <ul>
    119  *
    120  *   <li><p> {@link #clear} makes a buffer ready for a new sequence of
    121  *   channel-read or relative <i>put</i> operations: It sets the limit to the
    122  *   capacity and the position to zero.  </p></li>
    123  *
    124  *   <li><p> {@link #flip} makes a buffer ready for a new sequence of
    125  *   channel-write or relative <i>get</i> operations: It sets the limit to the
    126  *   current position and then sets the position to zero.  </p></li>
    127  *
    128  *   <li><p> {@link #rewind} makes a buffer ready for re-reading the data that
    129  *   it already contains: It leaves the limit unchanged and sets the position
    130  *   to zero.  </p></li>
    131  *
    132  * </ul>
    133  *
    134  *
    135  * <h2> Read-only buffers </h2>
    136  *
    137  * <p> Every buffer is readable, but not every buffer is writable.  The
    138  * mutation methods of each buffer class are specified as <i>optional
    139  * operations</i> that will throw a {@link ReadOnlyBufferException} when
    140  * invoked upon a read-only buffer.  A read-only buffer does not allow its
    141  * content to be changed, but its mark, position, and limit values are mutable.
    142  * Whether or not a buffer is read-only may be determined by invoking its
    143  * {@link #isReadOnly isReadOnly} method.
    144  *
    145  *
    146  * <h2> Thread safety </h2>
    147  *
    148  * <p> Buffers are not safe for use by multiple concurrent threads.  If a
    149  * buffer is to be used by more than one thread then access to the buffer
    150  * should be controlled by appropriate synchronization.
    151  *
    152  *
    153  * <h2> Invocation chaining </h2>
    154  *
    155  * <p> Methods in this class that do not otherwise have a value to return are
    156  * specified to return the buffer upon which they are invoked.  This allows
    157  * method invocations to be chained; for example, the sequence of statements
    158  *
    159  * <blockquote><pre>
    160  * b.flip();
    161  * b.position(23);
    162  * b.limit(42);</pre></blockquote>
    163  *
    164  * can be replaced by the single, more compact statement
    165  *
    166  * <blockquote><pre>
    167  * b.flip().position(23).limit(42);</pre></blockquote>
    168  *
    169  *
    170  * @author Mark Reinhold
    171  * @author JSR-51 Expert Group
    172  * @since 1.4
    173  */
    174 
    175 public abstract class Buffer {
    176 
    177     /**
    178      * The characteristics of Spliterators that traverse and split elements
    179      * maintained in Buffers.
    180      */
    181     static final int SPLITERATOR_CHARACTERISTICS =
    182         Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.ORDERED;
    183 
    184     // Invariants: mark <= position <= limit <= capacity
    185     private int mark = -1;
    186     private int position = 0;
    187     private int limit;
    188     private int capacity;
    189 
    190     // Used only by direct buffers
    191     // NOTE: hoisted here for speed in JNI GetDirectBufferAddress
    192     long address;
    193 
    194     // Creates a new buffer with the given mark, position, limit, and capacity,
    195     // after checking invariants.
    196     //
    197     Buffer(int mark, int pos, int lim, int cap) {       // package-private
    198         if (cap < 0)
    199             throw new IllegalArgumentException("Negative capacity: " + cap);
    200         this.capacity = cap;
    201         limit(lim);
    202         position(pos);
    203         if (mark >= 0) {
    204             if (mark > pos)
    205                 throw new IllegalArgumentException("mark > position: ("
    206                                                    + mark + " > " + pos + ")");
    207             this.mark = mark;
    208         }
    209     }
    210 
    211     /**
    212      * Returns this buffer's capacity.
    213      *
    214      * @return  The capacity of this buffer
    215      */
    216     public final int capacity() {
    217         return capacity;
    218     }
    219 
    220     /**
    221      * Returns this buffer's position.
    222      *
    223      * @return  The position of this buffer
    224      */
    225     public final int position() {
    226         return position;
    227     }
    228 
    229     /**
    230      * Sets this buffer's position.  If the mark is defined and larger than the
    231      * new position then it is discarded.
    232      *
    233      * @param  newPosition
    234      *         The new position value; must be non-negative
    235      *         and no larger than the current limit
    236      *
    237      * @return  This buffer
    238      *
    239      * @throws  IllegalArgumentException
    240      *          If the preconditions on <tt>newPosition</tt> do not hold
    241      */
    242     public final Buffer position(int newPosition) {
    243         if ((newPosition > limit) || (newPosition < 0))
    244             throw new IllegalArgumentException();
    245         position = newPosition;
    246         if (mark > position) mark = -1;
    247         return this;
    248     }
    249 
    250     /**
    251      * Returns this buffer's limit.
    252      *
    253      * @return  The limit of this buffer
    254      */
    255     public final int limit() {
    256         return limit;
    257     }
    258 
    259     /**
    260      * Sets this buffer's limit.  If the position is larger than the new limit
    261      * then it is set to the new limit.  If the mark is defined and larger than
    262      * the new limit then it is discarded.
    263      *
    264      * @param  newLimit
    265      *         The new limit value; must be non-negative
    266      *         and no larger than this buffer's capacity
    267      *
    268      * @return  This buffer
    269      *
    270      * @throws  IllegalArgumentException
    271      *          If the preconditions on <tt>newLimit</tt> do not hold
    272      */
    273     public final Buffer limit(int newLimit) {
    274         if ((newLimit > capacity) || (newLimit < 0))
    275             throw new IllegalArgumentException();
    276         limit = newLimit;
    277         if (position > limit) position = limit;
    278         if (mark > limit) mark = -1;
    279         return this;
    280     }
    281 
    282     /**
    283      * Sets this buffer's mark at its position.
    284      *
    285      * @return  This buffer
    286      */
    287     public final Buffer mark() {
    288         mark = position;
    289         return this;
    290     }
    291 
    292     /**
    293      * Resets this buffer's position to the previously-marked position.
    294      *
    295      * <p> Invoking this method neither changes nor discards the mark's
    296      * value. </p>
    297      *
    298      * @return  This buffer
    299      *
    300      * @throws  InvalidMarkException
    301      *          If the mark has not been set
    302      */
    303     public final Buffer reset() {
    304         int m = mark;
    305         if (m < 0)
    306             throw new InvalidMarkException();
    307         position = m;
    308         return this;
    309     }
    310 
    311     /**
    312      * Clears this buffer.  The position is set to zero, the limit is set to
    313      * the capacity, and the mark is discarded.
    314      *
    315      * <p> Invoke this method before using a sequence of channel-read or
    316      * <i>put</i> operations to fill this buffer.  For example:
    317      *
    318      * <blockquote><pre>
    319      * buf.clear();     // Prepare buffer for reading
    320      * in.read(buf);    // Read data</pre></blockquote>
    321      *
    322      * <p> This method does not actually erase the data in the buffer, but it
    323      * is named as if it did because it will most often be used in situations
    324      * in which that might as well be the case. </p>
    325      *
    326      * @return  This buffer
    327      */
    328     public final Buffer clear() {
    329         position = 0;
    330         limit = capacity;
    331         mark = -1;
    332         return this;
    333     }
    334 
    335     /**
    336      * Flips this buffer.  The limit is set to the current position and then
    337      * the position is set to zero.  If the mark is defined then it is
    338      * discarded.
    339      *
    340      * <p> After a sequence of channel-read or <i>put</i> operations, invoke
    341      * this method to prepare for a sequence of channel-write or relative
    342      * <i>get</i> operations.  For example:
    343      *
    344      * <blockquote><pre>
    345      * buf.put(magic);    // Prepend header
    346      * in.read(buf);      // Read data into rest of buffer
    347      * buf.flip();        // Flip buffer
    348      * out.write(buf);    // Write header + data to channel</pre></blockquote>
    349      *
    350      * <p> This method is often used in conjunction with the {@link
    351      * java.nio.ByteBuffer#compact compact} method when transferring data from
    352      * one place to another.  </p>
    353      *
    354      * @return  This buffer
    355      */
    356     public final Buffer flip() {
    357         limit = position;
    358         position = 0;
    359         mark = -1;
    360         return this;
    361     }
    362 
    363     /**
    364      * Rewinds this buffer.  The position is set to zero and the mark is
    365      * discarded.
    366      *
    367      * <p> Invoke this method before a sequence of channel-write or <i>get</i>
    368      * operations, assuming that the limit has already been set
    369      * appropriately.  For example:
    370      *
    371      * <blockquote><pre>
    372      * out.write(buf);    // Write remaining data
    373      * buf.rewind();      // Rewind buffer
    374      * buf.get(array);    // Copy data into array</pre></blockquote>
    375      *
    376      * @return  This buffer
    377      */
    378     public final Buffer rewind() {
    379         position = 0;
    380         mark = -1;
    381         return this;
    382     }
    383 
    384     /**
    385      * Returns the number of elements between the current position and the
    386      * limit.
    387      *
    388      * @return  The number of elements remaining in this buffer
    389      */
    390     public final int remaining() {
    391         return limit - position;
    392     }
    393 
    394     /**
    395      * Tells whether there are any elements between the current position and
    396      * the limit.
    397      *
    398      * @return  <tt>true</tt> if, and only if, there is at least one element
    399      *          remaining in this buffer
    400      */
    401     public final boolean hasRemaining() {
    402         return position < limit;
    403     }
    404 
    405     /**
    406      * Tells whether or not this buffer is read-only.
    407      *
    408      * @return  <tt>true</tt> if, and only if, this buffer is read-only
    409      */
    410     public abstract boolean isReadOnly();
    411 
    412     /**
    413      * Tells whether or not this buffer is backed by an accessible
    414      * array.
    415      *
    416      * <p> If this method returns <tt>true</tt> then the {@link #array() array}
    417      * and {@link #arrayOffset() arrayOffset} methods may safely be invoked.
    418      * </p>
    419      *
    420      * @return  <tt>true</tt> if, and only if, this buffer
    421      *          is backed by an array and is not read-only
    422      *
    423      * @since 1.6
    424      */
    425     public abstract boolean hasArray();
    426 
    427     /**
    428      * Returns the array that backs this
    429      * buffer&nbsp;&nbsp;<i>(optional operation)</i>.
    430      *
    431      * <p> This method is intended to allow array-backed buffers to be
    432      * passed to native code more efficiently. Concrete subclasses
    433      * provide more strongly-typed return values for this method.
    434      *
    435      * <p> Modifications to this buffer's content will cause the returned
    436      * array's content to be modified, and vice versa.
    437      *
    438      * <p> Invoke the {@link #hasArray hasArray} method before invoking this
    439      * method in order to ensure that this buffer has an accessible backing
    440      * array.  </p>
    441      *
    442      * @return  The array that backs this buffer
    443      *
    444      * @throws  ReadOnlyBufferException
    445      *          If this buffer is backed by an array but is read-only
    446      *
    447      * @throws  UnsupportedOperationException
    448      *          If this buffer is not backed by an accessible array
    449      *
    450      * @since 1.6
    451      */
    452     public abstract Object array();
    453 
    454     /**
    455      * Returns the offset within this buffer's backing array of the first
    456      * element of the buffer&nbsp;&nbsp;<i>(optional operation)</i>.
    457      *
    458      * <p> If this buffer is backed by an array then buffer position <i>p</i>
    459      * corresponds to array index <i>p</i>&nbsp;+&nbsp;<tt>arrayOffset()</tt>.
    460      *
    461      * <p> Invoke the {@link #hasArray hasArray} method before invoking this
    462      * method in order to ensure that this buffer has an accessible backing
    463      * array.  </p>
    464      *
    465      * @return  The offset within this buffer's array
    466      *          of the first element of the buffer
    467      *
    468      * @throws  ReadOnlyBufferException
    469      *          If this buffer is backed by an array but is read-only
    470      *
    471      * @throws  UnsupportedOperationException
    472      *          If this buffer is not backed by an accessible array
    473      *
    474      * @since 1.6
    475      */
    476     public abstract int arrayOffset();
    477 
    478     /**
    479      * Tells whether or not this buffer is
    480      * <a href="ByteBuffer.html#direct"><i>direct</i></a>.
    481      *
    482      * @return  <tt>true</tt> if, and only if, this buffer is direct
    483      *
    484      * @since 1.6
    485      */
    486     public abstract boolean isDirect();
    487 
    488 
    489     // -- Package-private methods for bounds checking, etc. --
    490 
    491     /**
    492      * Checks the current position against the limit, throwing a {@link
    493      * BufferUnderflowException} if it is not smaller than the limit, and then
    494      * increments the position.
    495      *
    496      * @return  The current position value, before it is incremented
    497      */
    498     final int nextGetIndex() {                          // package-private
    499         if (position >= limit)
    500             throw new BufferUnderflowException();
    501         return position++;
    502     }
    503 
    504     final int nextGetIndex(int nb) {                    // package-private
    505         if (limit - position < nb)
    506             throw new BufferUnderflowException();
    507         int p = position;
    508         position += nb;
    509         return p;
    510     }
    511 
    512     /**
    513      * Checks the current position against the limit, throwing a {@link
    514      * BufferOverflowException} if it is not smaller than the limit, and then
    515      * increments the position.
    516      *
    517      * @return  The current position value, before it is incremented
    518      */
    519     final int nextPutIndex() {                          // package-private
    520         if (position >= limit)
    521             throw new BufferOverflowException();
    522         return position++;
    523     }
    524 
    525     final int nextPutIndex(int nb) {                    // package-private
    526         if (limit - position < nb)
    527             throw new BufferOverflowException();
    528         int p = position;
    529         position += nb;
    530         return p;
    531     }
    532 
    533     /**
    534      * Checks the given index against the limit, throwing an {@link
    535      * IndexOutOfBoundsException} if it is not smaller than the limit
    536      * or is smaller than zero.
    537      */
    538     final int checkIndex(int i) {                       // package-private
    539         if ((i < 0) || (i >= limit))
    540             throw new IndexOutOfBoundsException();
    541         return i;
    542     }
    543 
    544     final int checkIndex(int i, int nb) {               // package-private
    545         if ((i < 0) || (nb > limit - i))
    546             throw new IndexOutOfBoundsException();
    547         return i;
    548     }
    549 
    550     final int markValue() {                             // package-private
    551         return mark;
    552     }
    553 
    554     final void truncate() {                             // package-private
    555         mark = -1;
    556         position = 0;
    557         limit = 0;
    558         capacity = 0;
    559     }
    560 
    561     final void discardMark() {                          // package-private
    562         mark = -1;
    563     }
    564 
    565     static void checkBounds(int off, int len, int size) { // package-private
    566         if ((off | len | (off + len) | (size - (off + len))) < 0)
    567             throw new IndexOutOfBoundsException();
    568     }
    569 
    570 }
    View Code

     注意:0<=mark<=position<=capacity

    测试代码:

     1 package com.dx.nios;
     2 
     3 import java.nio.ByteBuffer;
     4 
     5 import org.junit.Test;
     6 
     7 public class BufferTest {
     8 
     9     @Test
    10     public void TestBuffer() {
    11         ByteBuffer byteBuffer = ByteBuffer.allocate(10);
    12         
    13         System.out.println("------------allocate------------------");
    14         System.out.println(byteBuffer.position());
    15         System.out.println(byteBuffer.limit());
    16         System.out.println(byteBuffer.capacity());
    17         
    18         
    19         byteBuffer.put("abcde".getBytes());
    20                 
    21         System.out.println("------------put------------------");
    22         System.out.println(byteBuffer.position());
    23         System.out.println(byteBuffer.limit());
    24         System.out.println(byteBuffer.capacity());
    25         
    26         byteBuffer.flip();
    27         
    28         System.out.println("------------flip------------------");
    29         System.out.println(byteBuffer.position());
    30         System.out.println(byteBuffer.limit());
    31         System.out.println(byteBuffer.capacity());        
    32         
    33     }
    34 }

    输出结果:

    ------------allocate------------------
    0
    10
    10
    ------------put------------------
    5
    10
    10
    ------------flip------------------
    0
    5
    10

    分析:

    •  Buffer常用函数测试:

     1 package com.dx.nios;
     2 
     3 import java.nio.ByteBuffer;
     4 
     5 import org.junit.Test;
     6 
     7 public class BufferTest {
     8 
     9     @Test
    10     public void TestBuffer() {
    11         // 1.使用allocate()申请10个字节的缓冲区
    12         ByteBuffer byteBuffer = ByteBuffer.allocate(10);
    13         System.out.println("------------allocate------------------");
    14         System.out.println(byteBuffer.position());
    15         System.out.println(byteBuffer.limit());
    16         System.out.println(byteBuffer.capacity());
    17 
    18         // 2.使用put()存放5个字节到缓冲区
    19         byteBuffer.put("abcde".getBytes());
    20         System.out.println("------------put------------------");
    21         System.out.println(byteBuffer.position());
    22         System.out.println(byteBuffer.limit());
    23         System.out.println(byteBuffer.capacity());
    24 
    25         // 3.切换到读取数据模式
    26         byteBuffer.flip();
    27         System.out.println("------------flip------------------");
    28         System.out.println(byteBuffer.position());
    29         System.out.println(byteBuffer.limit());
    30         System.out.println(byteBuffer.capacity());
    31 
    32         // 4.从缓冲区中读取数据
    33         System.out.println("------------get------------------");
    34         byte[] bytes = new byte[byteBuffer.limit()];
    35         byteBuffer.get(bytes);
    36         System.out.println(new String(bytes, 0, bytes.length));
    37         System.out.println(byteBuffer.position());
    38         System.out.println(byteBuffer.limit());
    39         System.out.println(byteBuffer.capacity());
    40 
    41         // 5.设置为可重复读取
    42         System.out.println("------------rewind------------------");
    43         byteBuffer.rewind();
    44         System.out.println(byteBuffer.position());
    45         System.out.println(byteBuffer.limit());
    46         System.out.println(byteBuffer.capacity());
    47         byte[] bytes2 = new byte[byteBuffer.limit()];
    48         byteBuffer.get(bytes2);
    49         System.out.println(new String(bytes2, 0, bytes2.length));
    50         System.out.println(byteBuffer.position());
    51         System.out.println(byteBuffer.limit());
    52         System.out.println(byteBuffer.capacity());
    53 
    54         // 6。clear清空缓存区,但是内容没有被清掉,还存在。只不过这些数据状态为被遗忘状态。
    55         System.out.println("------------clear------------------");
    56         byteBuffer.clear();
    57         System.out.println(byteBuffer.position());
    58         System.out.println(byteBuffer.limit());
    59         System.out.println(byteBuffer.capacity());
    60         byte[] bytes3 = new byte[10];
    61         byteBuffer.get(bytes3);
    62         System.out.println(new String(bytes3, 0, bytes3.length));
    63     }
    64 }

    输出:

     1 ------------allocate------------------
     2 0
     3 10
     4 10
     5 ------------put------------------
     6 5
     7 10
     8 10
     9 ------------flip------------------
    10 0
    11 5
    12 10
    13 ------------get------------------
    14 abcde
    15 5
    16 5
    17 10
    18 ------------rewind------------------
    19 0
    20 5
    21 10
    22 abcde
    23 5
    24 5
    25 10
    26 ------------clear------------------
    27 0
    28 10
    29 10
    30 abcde
    • mark与reset的用法:

     1 @Test
     2     public void testMark() {
     3         ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
     4         byteBuffer.put("abcde".getBytes());
     5         byteBuffer.flip();
     6 
     7         byte[] bytes = new byte[byteBuffer.limit()];
     8         byteBuffer.get(bytes, 0, 2);
     9         System.out.println(new String(bytes, 0, bytes.length));
    10 
    11         System.out.println(byteBuffer.position());
    12         System.out.println(byteBuffer.limit());
    13         System.out.println(byteBuffer.capacity());
    14         
    15         byteBuffer.mark();
    16         System.out.println("---------mark----------");
    17         
    18         byteBuffer.get(bytes, 0, 2);
    19         System.out.println(new String(bytes, 0, bytes.length));
    20 
    21         System.out.println(byteBuffer.position());
    22         System.out.println(byteBuffer.limit());
    23         System.out.println(byteBuffer.capacity());
    24         
    25         byteBuffer.reset();    
    26         System.out.println("---------reset----------");
    27         
    28         System.out.println(byteBuffer.position());
    29         System.out.println(byteBuffer.limit());
    30         System.out.println(byteBuffer.capacity());
    31     }

    打印信息:

    ab
    2
    5
    1024
    ---------mark----------
    cd
    4
    5
    1024
    ---------reset----------
    2
    5
    1024

     
  • 相关阅读:
    委托与事件
    Winform 窗体闪烁 & 任务栏提示
    Main函数
    WPF数据虚拟化
    异步编程、线程和任务
    内存管理与垃圾回收
    Winform 获取桌面设备上下文
    全选,反选,全不选以及计算价格,删除
    全选、反选、删除
    解析数据图片自动轮播——圆点
  • 原文地址:https://www.cnblogs.com/yy3b2007com/p/7261025.html
Copyright © 2011-2022 走看看