`
Donald_Draper
  • 浏览: 984357 次
社区版块
存档分类
最新评论

netty 字节buf定义

阅读更多
netty 通道接口定义:http://donald-draper.iteye.com/blog/2392740
netty 抽象通道初始化:http://donald-draper.iteye.com/blog/2392801
netty 抽象Unsafe定义:http://donald-draper.iteye.com/blog/2393053
netty 通道Outbound缓冲区:http://donald-draper.iteye.com/blog/2393098
netty 抽象通道后续:http://donald-draper.iteye.com/blog/2393166
netty 抽象nio通道:http://donald-draper.iteye.com/blog/2393269
netty 抽象nio字节通道:http://donald-draper.iteye.com/blog/2393323
netty 抽象nio消息通道:http://donald-draper.iteye.com/blog/2393364
netty NioServerSocketChannel解析:http://donald-draper.iteye.com/blog/2393443
netty 通道配置接口定义:http://donald-draper.iteye.com/blog/2393484
netty 默认通道配置初始化:http://donald-draper.iteye.com/blog/2393504
netty 默认通道配置后续:http://donald-draper.iteye.com/blog/2393510
引言
前面两篇文章我们看了通道配置,先来简单回顾一下:
默认通道配置内部主要是配置消息大小估算器,字节buf分配器,接收字节buf分配器等属性。默认ServerSocket通道配置,与ServerSocket相关的配置委托给ServerSocket的相关方法,其他委托给父类默认通道配置。默认Socket通道配置,与Socket相关的配置委托给Socket的相关方法,其他委托给父类默认通道配置。

在上面的两篇文章中,我们有说过字节buf分配器,字节buf分配器可以创建direct和heap类型的ByteBuf,接下来的文章先看一下
字节buf接口的定义,再看字节buf分配器非配的direct和heap类型的字节buf实现。先从字节buf接口定义:
public abstract class ByteBuf implements ReferenceCounted, Comparable<ByteBuf> {


再看字节buf接口定义前,来看一下引用计数器接口的定义:
package io.netty.util;

/**
 * A reference-counted object that requires explicit deallocation.
 * 
 * When a new {@link ReferenceCounted} is instantiated, it starts with the reference count of {@code 1}.
 * {@link #retain()} increases the reference count, and {@link #release()} decreases the reference count.
 * If the reference count is decreased to {@code 0}, the object will be deallocated explicitly, and accessing
 * the deallocated object will usually result in an access violation.
 * 

 * 
 * If an object that implements {@link ReferenceCounted} is a container of other objects that implement
 * {@link ReferenceCounted}, the contained objects will also be released via {@link #release()} when the container's
 * reference count becomes 0.
 * 

 */
public interface ReferenceCounted {
    /**
     * Returns the reference count of this object.  If {@code 0}, it means this object has been deallocated.
     返回对象的引用计数器,为0,表示对象可以被回收
     */
    int refCnt();

    /**
     * Increases the reference count by {@code 1}.
     对象引用计数器自增1
     */
    ReferenceCounted retain();

    /**
     * Increases the reference count by the specified {@code increment}.
     增加引用计数器,增量为increment
     */
    ReferenceCounted retain(int increment);

    /**
     * Records the current access location of this object for debugging purposes.
     * If this object is determined to be leaked, the information recorded by this operation will be provided to you
     * via {@link ResourceLeakDetector}.  This method is a shortcut to {@link #touch(Object) touch(null)}.
     调试时,记录当前对象访问的位置。如果对象确定内存泄漏,可以通过ResourceLeakDetector获取操作的相关信息。
     此方法为 #touch(Object) touch(null)的快捷方式
     */
    ReferenceCounted touch();

    /**
     * Records the current access location of this object with an additional arbitrary information for debugging
     * purposes.  If this object is determined to be leaked, the information recorded by this operation will be
     * provided to you via {@link ResourceLeakDetector}.
     调试时,记录当前对象访问的位置。如果对象确定内存泄漏,可以通过ResourceLeakDetector获取操作的相关信息。
     */
    ReferenceCounted touch(Object hint);

    /**
     * Decreases the reference count by {@code 1} and deallocates this object if the reference count reaches at
     * {@code 0}.
     *自减对象引用计数器,如果引用数为0,则回收对象。当且仅当对象引用计数器为0,回收对象,返回true
     * @return {@code true} if and only if the reference count became {@code 0} and this object has been deallocated
     */
    boolean release();

    /**
     * Decreases the reference count by the specified {@code decrement} and deallocates this object if the reference
     * count reaches at {@code 0}.
     *减对象引用计数器,减量为decrement,如果引用数为0,则回收对象。当且仅当对象引用计数器为0,回收对象,返回true
     * @return {@code true} if and only if the reference count became {@code 0} and this object has been deallocated
     */
    boolean release(int decrement);
}


从上面可以看出,对象引用计数器ReferenceCounted,主要记录对象的引用数量,当引用数量为0时,表示可以回收对象,在调试模式下,如果发现对象出现内存泄漏,可以用touch方法记录操作的相关信息,通过ResourceLeakDetector获取操作的相关信息,以便分析内存泄漏的原因。

再来看字节buf的接口定义:
package io.netty.buffer;

import io.netty.util.ByteProcessor;
import io.netty.util.ReferenceCounted;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.FileChannel;
import java.nio.channels.GatheringByteChannel;
import java.nio.channels.ScatteringByteChannel;
import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;

/**
 * A random and sequential accessible sequence of zero or more bytes (octets).
 * This interface provides an abstract view for one or more primitive byte
 * arrays ({@code byte[]}) and {@linkplain ByteBuffer NIO buffers}.
 *字节缓冲ByteBuf是一个可随机方法字节序列,字节数可以为0或更多。
 这个方法提供了一个或更多原始字节数组和java nio ByteBuffer的抽象视图。
 * <h3>Creation of a buffer</h3>
 *创建buf
 * It is recommended to create a new buffer using the helper methods in
 * {@link Unpooled} rather than calling an individual implementation's
 * constructor.
 *强烈建议使用Unpooled的辅助方法创建一个字节buf,而不是调用buf具体实现的构造方法。
 * <h3>Random Access Indexing</h3>
 *随机访问索引
 * Just like an ordinary primitive byte array, {@link ByteBuf} uses
 * [url=http://en.wikipedia.org/wiki/Zero-based_numbering]zero-based indexing[/url].
 * It means the index of the first byte is always {@code 0} and the index of the last byte is
 * always {@link #capacity() capacity - 1}.  For example, to iterate all bytes of a buffer, you
 * can do the following, regardless of its internal implementation:
 *如一般的字节数组一样,字节buf索引也是从0开始。意味着第一个字节的索引总是为0,最后一个字节的
 索引总是为#capacity() capacity - 1。比如,遍历buf中的所有字节,忽略具体实现的情况下,
 可以按如下code
 * <pre>
 * {@link ByteBuf} buffer = ...;
 * for (int i = 0; i < buffer.capacity(); i ++) {
 *     byte b = buffer.getByte(i);
 *     System.out.println((char) b);
 * }
 * </pre>
 *
 * <h3>Sequential Access Indexing</h3>
 *顺序访问索引
 * {@link ByteBuf} provides two pointer variables to support sequential
 * read and write operations - {@link #readerIndex() readerIndex} for a read
 * operation and {@link #writerIndex() writerIndex} for a write operation
 * respectively.  The following diagram shows how a buffer is segmented into
 * three areas by the two pointers:
 *字节buf提供了两个索引支持顺序读写操作,#readerIndex返回读操作使用的读索引readerIndex,
#writerIndex返回写操作使用的写索引writerIndex。下图展示读写索引如何将buf分为三段。
 * <pre>
 *      +-------------------+------------------+------------------+
 *      | discardable bytes |  readable bytes  |  writable bytes  |
 *      |                   |     (CONTENT)    |                  |
 *      +-------------------+------------------+------------------+
 *      |                   |                  |                  |
 *      0      <=      readerIndex   <=   writerIndex    <=    capacity
 * </pre>
 *
 * <h4>Readable bytes (the actual content)</h4>
 *可读字节(实际内容)
 * This segment is where the actual data is stored.  Any operation whose name
 * starts with {@code read} or {@code skip} will get or skip the data at the
 * current {@link #readerIndex() readerIndex} and increase it by the number of
 * read bytes.  If the argument of the read operation is also a
 * {@link ByteBuf} and no destination index is specified, the specified
 * buffer's {@link #writerIndex() writerIndex} is increased together.
 这段内容为实际存储的数据。任何以read和skip开头的操作方法,将会从当前的读索引开始,
 并增加读索引,增量为读取的字节数。如果读操作的参数为字节buf,并且没有目的索引,
 那么目的buf写索引也会增加。
 * <p>
 * If there's not enough content left, {@link IndexOutOfBoundsException} is
 * raised.  The default value of newly allocated, wrapped or copied buffer's
 * {@link #readerIndex() readerIndex} is {@code 0}.
 *如果没有足够的内容,将会抛出IndexOutOfBoundsException异常。默认新分配,
 copy,包装的字节buf的读索引为0。
 * <pre>
 * // Iterates the readable bytes of a buffer.
 * {@link ByteBuf} buffer = ...;
 * while (buffer.isReadable()) {
 *     System.out.println(buffer.readByte());
 * }
 * </pre>
 *
 * <h4>Writable bytes</h4>
 *可写字节
 * This segment is a undefined space which needs to be filled.  Any operation
 * whose name starts with {@code write} will write the data at the current
 * {@link #writerIndex() writerIndex} and increase it by the number of written
 * bytes.  If the argument of the write operation is also a {@link ByteBuf},
 * and no source index is specified, the specified buffer's
 * {@link #readerIndex() readerIndex} is increased together.
 此段是需要填充的无定义空间。任何以write开头的操作方法,将会从当前的写索引开始写字节数据,
 并增加写索引,增量为写的字节数。如果写操作的参数为字节buf,并且没有源索引,则源buf的读索引
 将会增加
 * <p>
 * If there's not enough writable bytes left, {@link IndexOutOfBoundsException}
 * is raised.  The default value of newly allocated buffer's
 * {@link #writerIndex() writerIndex} is {@code 0}.  The default value of
 * wrapped or copied buffer's {@link #writerIndex() writerIndex} is the
 * {@link #capacity() capacity} of the buffer.
 *
 如果没有足够的可写字节,将抛出IndexOutOfBoundsException异常。默认新分配的buf的写索引为0。
copy,包装的字节buf的写索引为#capacity() capacity
 * <pre>
 * // Fills the writable bytes of a buffer with random integers.
 写随机整数到buf
 * {@link ByteBuf} buffer = ...;
 * while (buffer.maxWritableBytes() >= 4) {
 *     buffer.writeInt(random.nextInt());
 * }
 * </pre>
 *
 * <h4>Discardable bytes</h4>
 *可丢弃的字节数
 * This segment contains the bytes which were read already by a read operation.
 * Initially, the size of this segment is {@code 0}, but its size increases up
 * to the {@link #writerIndex() writerIndex} as read operations are executed.
 * The read bytes can be discarded by calling {@link #discardReadBytes()} to
 * reclaim unused area as depicted by the following diagram:
 *这段包含了读操作已经读取的字节。初始情况下,这段长度为0,但是这段的长度随着
 读操作的执行,增加至写索引。这段数据可以调用#discardReadBytes方法丢弃,
 并重新收回没用的区域,具体描述如下图:
 * <pre>
 *  BEFORE discardReadBytes()
 *
 *      +-------------------+------------------+------------------+
 *      | discardable bytes |  readable bytes  |  writable bytes  |
 *      +-------------------+------------------+------------------+
 *      |                   |                  |                  |
 *      0      <=      readerIndex   <=   writerIndex    <=    capacity
 *
 *
 *  AFTER discardReadBytes()
 *
 *      +------------------+--------------------------------------+
 *      |  readable bytes  |    writable bytes (got more space)   |
 *      +------------------+--------------------------------------+
 *      |                  |                                      |
 * readerIndex (0) <= writerIndex (decreased)        <=        capacity
 * </pre>
 *
 * Please note that there is no guarantee about the content of writable bytes
 * after calling {@link #discardReadBytes()}.  The writable bytes will not be
 * moved in most cases and could even be filled with completely different data
 * depending on the underlying buffer implementation.
 *需要注意的是,在丢弃已经读取的字节时,并不能保证可写字节的内容。可写字节在大多数情况下不会
 移动,甚至可能填充不同的数据,这个依赖于具体的buf实现。
 * <h4>Clearing the buffer indexes</h4>
 *清除buf索引
 * You can set both {@link #readerIndex() readerIndex} and
 * {@link #writerIndex() writerIndex} to {@code 0} by calling {@link #clear()}.
 * It does not clear the buffer content (e.g. filling with {@code 0}) but just
 * clears the two pointers.  Please also note that the semantic of this
 * operation is different from {@link ByteBuffer#clear()}.
 *我们可以调用#clear方法,设置读写索引为0。clear方法不会清除buf中的数据,仅仅调整
 读写索引。需要注意的是此方法不同于java nio ByteBuffer#clear方法。
 * <pre>
 *  BEFORE clear()
 *
 *      +-------------------+------------------+------------------+
 *      | discardable bytes |  readable bytes  |  writable bytes  |
 *      +-------------------+------------------+------------------+
 *      |                   |                  |                  |
 *      0      <=      readerIndex   <=   writerIndex    <=    capacity
 *
 *
 *  AFTER clear()
 *
 *      +---------------------------------------------------------+
 *      |             writable bytes (got more space)             |
 *      +---------------------------------------------------------+
 *      |                                                         |
 *      0 = readerIndex = writerIndex            <=            capacity
 * </pre>
 *
 * <h3>Search operations</h3>
 *搜索操作
 * For simple single-byte searches, use {@link #indexOf(int, int, byte)} and {@link #bytesBefore(int, int, byte)}.
 * {@link #bytesBefore(byte)} is especially useful when you deal with a {@code NUL}-terminated string.
 * For complicated searches, use {@link #forEachByte(int, int, ByteProcessor)} with a {@link ByteProcessor}
 * implementation.
 对于简单的单个字节搜索,可是使用#indexOf和#bytesBefore方法。当需要处理一个空字节NUL(0x00)时,
 #bytesBefore方法特别有用。 比如一些复杂的搜索,可以使用字节处理器ByteProcessor版的#forEachByte方法。
 *
 * <h3>Mark and reset</h3>
 *标记和重置
 * There are two marker indexes in every buffer. One is for storing
 * {@link #readerIndex() readerIndex} and the other is for storing
 * {@link #writerIndex() writerIndex}.  You can always reposition one of the
 * two indexes by calling a reset method.  It works in a similar fashion to
 * the mark and reset methods in {@link InputStream} except that there's no
 * {@code readlimit}.
 *在每个buf中有两个标记索引,一个是存储读索引的,一个是存储写索引的。你可以
 调用reset方法,重置读、写索引到标记的位置。除了没有readlimit之外,与输入流中标记和重置方法
 相似。
 * <h3>Derived buffers</h3>
 *衍生buf
 * You can create a view of an existing buffer by calling one of the following methods:
 你可通过如下方法,创建buf的视图:
 * [list]
 *   [*]{@link #duplicate()}

 *   [*]{@link #slice()}

 *   [*]{@link #slice(int, int)}

 *   [*]{@link #readSlice(int)}

 *   [*]{@link #retainedDuplicate()}

 *   [*]{@link #retainedSlice()}

 *   [*]{@link #retainedSlice(int, int)}

 *   [*]{@link #readRetainedSlice(int)}

 * [/list]
 * A derived buffer will have an independent {@link #readerIndex() readerIndex},
 * {@link #writerIndex() writerIndex} and marker indexes, while it shares
 * other internal data representation, just like a NIO buffer does.
 衍生buf,拥有自己独立的读写索引的标记索引,共享其他内部数据,就像java nio ByteBuffer
 * <p>
 * In case a completely fresh copy of an existing buffer is required, please
 * call {@link #copy()} method instead.
 *假如需要当前buf的完全拷贝,可以使用copy方法。
 * <h4>Non-retained and retained derived buffers</h4>
 *非retained和retained衍生buf
 * Note that the {@link #duplicate()}, {@link #slice()}, {@link #slice(int, int)} and {@link #readSlice(int)} does NOT
 * call {@link #retain()} on the returned derived buffer, and thus its reference count will NOT be increased. If you
 * need to create a derived buffer with increased reference count, consider using {@link #retainedDuplicate()},
 * {@link #retainedSlice()}, {@link #retainedSlice(int, int)} and {@link #readRetainedSlice(int)} which may return
 * a buffer implementation that produces less garbage.
 *注意#duplicate,#slice,#slice,#readSlice方法不会在衍生buf中调用#retain方法,这样buf的引用计数器将不会增加。
 如果需要创建衍生buf,需要增加引用计数器,可以考虑上述方法的#retained*版本方法,这样可能会产生一点内存垃圾。
 * <h3>Conversion to existing JDK types</h3>
 *转换ByteBuf为JDK 类型
 * <h4>Byte array</h4>
 *字节数组
 * If a {@link ByteBuf} is backed by a byte array (i.e. {@code byte[]}),
 * you can access it directly via the {@link #array()} method.  To determine
 * if a buffer is backed by a byte array, {@link #hasArray()} should be used.
 *如果字节是一个字节数组,你可以直接使用#array访问。判断一个方法是否为字节数组,可以
 使用#hasArray方法
 * <h4>NIO Buffers</h4>
 *nio ByteBuffer
 * If a {@link ByteBuf} can be converted into an NIO {@link ByteBuffer} which shares its
 * content (i.e. view buffer), you can get it via the {@link #nioBuffer()} method.  To determine
 * if a buffer can be converted into an NIO buffer, use {@link #nioBufferCount()}.
 *如果字节buf可以转换为java nio ByteBuffer,你可以调用#nioBuffer方法共享buf内容。
 你可以使用#nioBufferCount来判断字节buf可不可以转换为java nio ByteBuffer
 * <h4>Strings</h4>
 *字符串
 * Various {@link #toString(Charset)} methods convert a {@link ByteBuf}
 * into a {@link String}.  Please note that {@link #toString()} is not a
 * conversion method.
 *#toString(Charset)方法转换字节buf为字符串,注意#toString不是一个转换方法
 * <h4>I/O Streams</h4>
 *IO流
 * Please refer to {@link ByteBufInputStream} and
 * {@link ByteBufOutputStream}.
 参考ByteBufInputStream和ByteBufOutputStream
 */
@SuppressWarnings("ClassMayBeInterface")
public abstract class ByteBuf implements ReferenceCounted, Comparable<ByteBuf> {

    /**
     * Returns the number of bytes (octets) this buffer can contain.
     获取buf容量
     */
    public abstract int capacity();

    /**
     * Adjusts the capacity of this buffer.  If the {@code newCapacity} is less than the current
     * capacity, the content of this buffer is truncated.  If the {@code newCapacity} is greater
     * than the current capacity, the buffer is appended with unspecified data whose length is
     * {@code (newCapacity - currentCapacity)}.
     调整buf的容量,如果容量小于原始buf容量,则truncated buf的内容,如果新增量大于原始容量,
     则buffer将会添加不确定的数,其长度为newCapacity - currentCapacity
     */
    public abstract ByteBuf capacity(int newCapacity);

    /**
     * Returns the maximum allowed capacity of this buffer.  If a user attempts to increase the
     * capacity of this buffer beyond the maximum capacity using {@link #capacity(int)} or
     * {@link #ensureWritable(int)}, those methods will raise an
     * {@link IllegalArgumentException}.
     返回buf的最大允许容量。如果用户尝试用 #capacity(int)和 #ensureWritable(int)方法,
     增加buf容量超过最大容量,将会抛出非法参数异常
     */
    public abstract int maxCapacity();

    /**
     * Returns the {@link ByteBufAllocator} which created this buffer.
     返回创建buf的字节buf分配器
     */
    public abstract ByteBufAllocator alloc();

    /**
     * Returns the [url=http://en.wikipedia.org/wiki/Endianness]endianness[/url]
     * of this buffer.
     *已丢弃
     * @deprecated use the Little Endian accessors, e.g. {@code getShortLE}, {@code getIntLE}
     * instead of creating a buffer with swapped {@code endianness}.
     */
    @Deprecated
    public abstract ByteOrder order();

    /**
     * Returns a buffer with the specified {@code endianness} which shares the whole region,
     * indexes, and marks of this buffer.  Modifying the content, the indexes, or the marks of the
     * returned buffer or this buffer affects each other's content, indexes, and marks.  If the
     * specified {@code endianness} is identical to this buffer's byte order, this method can
     * return {@code this}.  This method does not modify {@code readerIndex} or {@code writerIndex}
     * of this buffer.
     *已丢弃
     * @deprecated use the Little Endian accessors, e.g. {@code getShortLE}, {@code getIntLE}
     * instead of creating a buffer with swapped {@code endianness}.
     */
    @Deprecated
    public abstract ByteBuf order(ByteOrder endianness);

    /**
     * Return the underlying buffer instance if this buffer is a wrapper of another buffer.
     *如果buf为另一个buf包装类,返回底层buf实例,即返回未包装的buf
     * @return {@code null} if this buffer is not a wrapper
     */
    public abstract ByteBuf unwrap();

    /**
     * Returns {@code true} if and only if this buffer is backed by an
     * NIO direct buffer.
     判断buf是否是direct类型
     */
    public abstract boolean isDirect();

    /**
     * Returns {@code true} if and only if this buffer is read-only.
     判断buf是否可读
     */
    public abstract boolean isReadOnly();

    /**
     * Returns a read-only version of this buffer.
     返回buf的只读版本
     */
    public abstract ByteBuf asReadOnly();

    /**
     * Returns the {@code readerIndex} of this buffer.
     获取buf的读索引
     */
    public abstract int readerIndex();

    /**
     * Sets the {@code readerIndex} of this buffer.
     *设置buf的读索引
     * @throws IndexOutOfBoundsException
     *         if the specified {@code readerIndex} is
     *            less than {@code 0} or
     *            greater than {@code this.writerIndex}
     */
    public abstract ByteBuf readerIndex(int readerIndex);

    /**
     * Returns the {@code writerIndex} of this buffer.
     获取buf的写索引
     */
    public abstract int writerIndex();

    /**
     * Sets the {@code writerIndex} of this buffer.
     *设置buf的写索引
     * @throws IndexOutOfBoundsException
     *         if the specified {@code writerIndex} is
     *            less than {@code this.readerIndex} or
     *            greater than {@code this.capacity}
     */
    public abstract ByteBuf writerIndex(int writerIndex);

    /**
     * Sets the {@code readerIndex} and {@code writerIndex} of this buffer
     * in one shot.  This method is useful when you have to worry about the
     * invocation order of {@link #readerIndex(int)} and {@link #writerIndex(int)}
     * methods.  For example, the following code will fail:
     *设置buf读写索引的快捷方式。当你不得不关心读索引设置和写索引设置的顺序时,这个方法,非常有用。
     以下代码将会失败:
     * <pre>
     * // Create a buffer whose readerIndex, writerIndex and capacity are
     * // 0, 0 and 8 respectively.
     * {@link ByteBuf} buf = {@link Unpooled}.buffer(8);
     *
     * // IndexOutOfBoundsException is thrown because the specified
     * // readerIndex (2) cannot be greater than the current writerIndex (0).
     读索引不能大于当前的写索引
     * buf.readerIndex(2);
     * buf.writerIndex(4);
     * </pre>
     *
     * The following code will also fail:
     *同样下面的代码会失败
     * <pre>
     * // Create a buffer whose readerIndex, writerIndex and capacity are
     * // 0, 8 and 8 respectively.
     * {@link ByteBuf} buf = {@link Unpooled}.wrappedBuffer(new byte[8]);
     *
     * // readerIndex becomes 8.
     * buf.readLong();
     *
     * // IndexOutOfBoundsException is thrown because the specified
     * // writerIndex (4) cannot be less than the current readerIndex (8).
     写索引小于读索引
     * buf.writerIndex(4);
     * buf.readerIndex(2);
     * </pre>
     *
     * By contrast, this method guarantees that it never
     * throws an {@link IndexOutOfBoundsException} as long as the specified
     * indexes meet basic constraints, regardless what the current index
     * values of the buffer are:
     *相比之下,setIndex方法可以保证只要索引满足基本的约束,无论当前buf索引的值是什么,
     索引越界异常不会抛出.
     * <pre>
     * // No matter what the current state of the buffer is, the following
     * // call always succeeds as long as the capacity of the buffer is not
     * // less than 4.
     只要buf的容量大于4,就不会抛出异常
     * buf.setIndex(2, 4);
     * </pre>
     *
     * @throws IndexOutOfBoundsException
     *         if the specified {@code readerIndex} is less than 0,
     *         if the specified {@code writerIndex} is less than the specified
     *         {@code readerIndex} or if the specified {@code writerIndex} is
     *         greater than {@code this.capacity}
     */
    public abstract ByteBuf setIndex(int readerIndex, int writerIndex);

    /**
     * Returns the number of readable bytes which is equal to
     获取buf可读字节数为writerIndex - readerIndex
     * {@code (this.writerIndex - this.readerIndex)}.
     */
    public abstract int readableBytes();

    /**
     * Returns the number of writable bytes which is equal to
     获取buf可写字节数为capacity - writerIndex
     * {@code (this.capacity - this.writerIndex)}.
     */
    public abstract int writableBytes();

    /**
     * Returns the maximum possible number of writable bytes, which is equal to
     * {@code (this.maxCapacity - this.writerIndex)}.
     当前buf可写的最大字节数为maxCapacity - writerIndex
     */
    public abstract int maxWritableBytes();

    /**
     * Returns {@code true}
     * if and only if {@code (this.writerIndex - this.readerIndex)} is greater
     * than {@code 0}.
     获取buf是否可读,如果当前可读字节数大于0,表示可读,返回true
     */
    public abstract boolean isReadable();

    /**
     * Returns {@code true} if and only if this buffer contains equal to or more than the specified number of elements.
     buf的可读字节数据是否大于size
     */
    public abstract boolean isReadable(int size);

    /**
     * Returns {@code true}
     * if and only if {@code (this.capacity - this.writerIndex)} is greater
     * than {@code 0}.
     buf是否可写,即this.capacity - this.writerIndex是否大于0
     */
    public abstract boolean isWritable();

    /**
     * Returns {@code true} if and only if this buffer has enough room to allow writing the specified number of
     * elements.
     判断当前buf是否可容下size字节
     */
    public abstract boolean isWritable(int size);

    /**
     * Sets the {@code readerIndex} and {@code writerIndex} of this buffer to
     * {@code 0}.
     重置buf的读写索引为0,等同于setIndex(0, 0)
     * This method is identical to {@link #setIndex(int, int) setIndex(0, 0)}.
     * <p>
     * Please note that the behavior of this method is different
     * from that of NIO buffer, which sets the {@code limit} to
     * the {@code capacity} of the buffer.
     主要此方法,不同于Java nio buffer,设置buf的limit的位置为capacity
     */
    public abstract ByteBuf clear();

    /**
     * Marks the current {@code readerIndex} in this buffer.  You can
     * reposition the current {@code readerIndex} to the marked
     * {@code readerIndex} by calling {@link #resetReaderIndex()}.
     * The initial value of the marked {@code readerIndex} is {@code 0}.
     标记当前buf的读索引。我们可以调用#resetReaderIndex方法,重回标记的读索引位置。
     初始标记位置为0。
     */
    public abstract ByteBuf markReaderIndex();

    /**
     * Repositions the current {@code readerIndex} to the marked
     * {@code readerIndex} in this buffer.
     *重回标记的读索引位置
     * @throws IndexOutOfBoundsException
     *         if the current {@code writerIndex} is less than the marked
     *         {@code readerIndex}
     */
    public abstract ByteBuf resetReaderIndex();

    /**
     * Marks the current {@code writerIndex} in this buffer.  You can
     * reposition the current {@code writerIndex} to the marked
     * {@code writerIndex} by calling {@link #resetWriterIndex()}.
     * The initial value of the marked {@code writerIndex} is {@code 0}.
     标记当前buf的写索引。我们可以调用#resetWriterIndex方法,重回标记的写索引位置。
     初始标记位置为0。
     */
    public abstract ByteBuf markWriterIndex();

    /**
     * Repositions the current {@code writerIndex} to the marked
     * {@code writerIndex} in this buffer.
     *重回标记的写索引位置
     * @throws IndexOutOfBoundsException
     *         if the current {@code readerIndex} is greater than the marked
     *         {@code writerIndex}
     */
    public abstract ByteBuf resetWriterIndex();

    /**
     * Discards the bytes between the 0th index and {@code readerIndex}.
     * It moves the bytes between {@code readerIndex} and {@code writerIndex}
     * to the 0th index, and sets {@code readerIndex} and {@code writerIndex}
     * to {@code 0} and {@code oldWriterIndex - oldReaderIndex} respectively.
     丢弃0索引到当前读索引的数据。并移到读索引到写索引之间的数据,到0索引位置上,
     重置读索引为0,写索引为oldWriterIndex - oldReaderIndex
     * <p>
     * Please refer to the class documentation for more detailed explanation.
     更详细的扩展,请参考具体的class文档
     */
    public abstract ByteBuf discardReadBytes();

    /**
     * Similar to {@link ByteBuf#discardReadBytes()} except that this method might discard
     * some, all, or none of read bytes depending on its internal implementation to reduce
     * overall memory bandwidth consumption at the cost of potentially additional memory
     * consumption.
     与ByteBuf#discardReadBytes方法相似,此方可能会在内存出现负载时,丢弃一些或所有,
     或不丢弃可读字节数据,具体依赖具体的实现,以减少内存的使用量。
     */
    public abstract ByteBuf discardSomeReadBytes();

    /**
     * Makes sure the number of {@linkplain #writableBytes() the writable bytes}
     * is equal to or greater than the specified value.  If there is enough
     * writable bytes in this buffer, this method returns with no side effect.
     * Otherwise, it raises an {@link IllegalArgumentException}.
     确保当前buf可以容下minWritableBytes个字节数据,如果buf足够写,则方法返回没有任何影响,
     否则抛出非法参数异常
     *
     * @param minWritableBytes
     *        the expected minimum number of writable bytes
     * @throws IndexOutOfBoundsException
     *         if {@link #writerIndex()} + {@code minWritableBytes} > {@link #maxCapacity()}
     */
    public abstract ByteBuf ensureWritable(int minWritableBytes);

    /**
     * Tries to make sure the number of {@linkplain #writableBytes() the writable bytes}
     * is equal to or greater than the specified value.  Unlike {@link #ensureWritable(int)},
     * this method does not raise an exception but returns a code.
     *尝试确保buf可以写minWritableBytes字节数据。与#ensureWritable(int)方法不同的时,不会抛出异常
     * @param minWritableBytes
     *        the expected minimum number of writable bytes
     * @param force
     *        When {@link #writerIndex()} + {@code minWritableBytes} > {@link #maxCapacity()}:
     *        [list]
     *        [*]{@code true} - the capacity of the buffer is expanded to {@link #maxCapacity()}

     *        [*]{@code false} - the capacity of the buffer is unchanged

     当force为true,空间不足时,扩展buf容量为最大容量;
     false表示,空间不足时,容量没有任何改变
     *        [/list]
     * @return {@code 0} if the buffer has enough writable bytes, and its capacity is unchanged.
     *         {@code 1} if the buffer does not have enough bytes, and its capacity is unchanged.
     *         {@code 2} if the buffer has enough writable bytes, and its capacity has been increased.
     *         {@code 3} if the buffer does not have enough bytes, but its capacity has been
     *                   increased to its maximum.
     返回代码0,表示buf可以容下minWritableBytes个字节数据;
     1表示,没有足够的空间可写,容量没有变化;
     2表示,buf可以容下minWritableBytes个字节数据,容量扩展;
     3表示,buf空间不够,容量扩展至最大值。
     */
    public abstract int ensureWritable(int minWritableBytes, boolean force);

  

    /**
     * Gets a byte at the specified absolute {@code index} in this buffer.
     * This method does not modify {@code readerIndex} or {@code writerIndex} of
     * this buffer.
     *
     获取指定索引位置的字节,此方法不会修改读写索引
     * @throws IndexOutOfBoundsException
     *         if the specified {@code index} is less than {@code 0} or
     *         {@code index + 1} is greater than {@code this.capacity}
     */
    public abstract byte  getByte(int index);

    
    /**
     * Transfers this buffer's data to the specified destination starting at
     * the specified absolute {@code index} until the destination becomes
     * non-writable.  This method is basically same with
     * {@link #getBytes(int, ByteBuf, int, int)}, except that this
     * method increases the {@code writerIndex} of the destination by the
     * number of the transferred bytes while
     * {@link #getBytes(int, ByteBuf, int, int)} does not.
     * This method does not modify {@code readerIndex} or {@code writerIndex} of
     * the source buffer (i.e. {@code this}).
     *从当前buf的index绝对索引开始,转移当前buf的数据到dst buf中。此方法与#getBytes(int, ByteBuf, int, int)方法相似,
     不同的时,此方法将会改变dst buf的写索引,而#getBytes(int, ByteBuf, int, int)不会。此方法不会改变当前buf的
     读写索引。
     * @throws IndexOutOfBoundsException
     *         if the specified {@code index} is less than {@code 0} or
     *         if {@code index + dst.writableBytes} is greater than
     *            {@code this.capacity}
     */
    public abstract ByteBuf getBytes(int index, ByteBuf dst);

    /**
     * Transfers this buffer's data to the specified destination starting at
     * the specified absolute {@code index}.  This method is basically same
     * with {@link #getBytes(int, ByteBuf, int, int)}, except that this
     * method increases the {@code writerIndex} of the destination by the
     * number of the transferred bytes while
     * {@link #getBytes(int, ByteBuf, int, int)} does not.
     * This method does not modify {@code readerIndex} or {@code writerIndex} of
     * the source buffer (i.e. {@code this}).
     *与上面方法不同的是,转移的数据的长度为length
     * @param length the number of bytes to transfer
     *
     * @throws IndexOutOfBoundsException
     *         if the specified {@code index} is less than {@code 0},
     *         if {@code index + length} is greater than
     *            {@code this.capacity}, or
     *         if {@code length} is greater than {@code dst.writableBytes}
     */
    public abstract ByteBuf getBytes(int index, ByteBuf dst, int length);

    /**
     * Transfers this buffer's data to the specified destination starting at
     * the specified absolute {@code index}.
     * This method does not modify {@code readerIndex} or {@code writerIndex}
     * of both the source (i.e. {@code this}) and the destination.
     *从当前buf的绝对索引index开始,转移length长度的数据到dst buf中,dstIndex绝对索引开始,
     此方法不会修改源buf和目的buf的读写索引位置。
     * @param dstIndex the first index of the destination
     * @param length   the number of bytes to transfer
     *
     * @throws IndexOutOfBoundsException
     *         if the specified {@code index} is less than {@code 0},
     *         if the specified {@code dstIndex} is less than {@code 0},
     *         if {@code index + length} is greater than
     *            {@code this.capacity}, or
     *         if {@code dstIndex + length} is greater than
     *            {@code dst.capacity}
     */
    public abstract ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length);

    /**
     * Transfers this buffer's data to the specified destination starting at
     * the specified absolute {@code index}.
     * This method does not modify {@code readerIndex} or {@code writerIndex} of
     * this buffer
     *从当前buf的绝对index开始,转移数据到,目的dst 字节数据中,此方法不会修改当前buf的读写索引。
     * @throws IndexOutOfBoundsException
     *         if the specified {@code index} is less than {@code 0} or
     *         if {@code index + dst.length} is greater than
     *            {@code this.capacity}
     */
    public abstract ByteBuf getBytes(int index, byte[] dst);

    /**
     * Transfers this buffer's data to the specified destination starting at
     * the specified absolute {@code index}.
     * This method does not modify {@code readerIndex} or {@code writerIndex}
     * of this buffer.
     *与上面方法是,转移的字节长度为length,从目的字节数组的dstIndex索引开始
     * @param dstIndex the first index of the destination
     * @param length   the number of bytes to transfer
     *
     * @throws IndexOutOfBoundsException
     *         if the specified {@code index} is less than {@code 0},
     *         if the specified {@code dstIndex} is less than {@code 0},
     *         if {@code index + length} is greater than
     *            {@code this.capacity}, or
     *         if {@code dstIndex + length} is greater than
     *            {@code dst.length}
     */
    public abstract ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length);

    /**
     * Transfers this buffer's data to the specified destination starting at
     * the specified absolute {@code index} until the destination's position
     * reaches its limit.
     * This method does not modify {@code readerIndex} or {@code writerIndex} of
     * this buffer while the destination's {@code position} will be increased.
     *从当前buf的绝对索引index开始,转移数据到目的nio buf中,直至到达目的nio buf的limit的位置
     ,此方法不会修改当前buf的读写索引,会修改nio buf的位置索引position
     * @throws IndexOutOfBoundsException
     *         if the specified {@code index} is less than {@code 0} or
     *         if {@code index + dst.remaining()} is greater than
     *            {@code this.capacity}
     */
    public abstract ByteBuf getBytes(int index, ByteBuffer dst);

    /**
     * Transfers this buffer's data to the specified stream starting at the
     * specified absolute {@code index}.
     * This method does not modify {@code readerIndex} or {@code writerIndex} of
     * this buffer.
     *从当前buf的绝对索引index开始,转移数据到目的OutputStream中,直至到达目的nio buf的limit的位置
     ,此方法不会修改当前buf的读写索引
     * @param length the number of bytes to transfer
     *
     * @throws IndexOutOfBoundsException
     *         if the specified {@code index} is less than {@code 0} or
     *         if {@code index + length} is greater than
     *            {@code this.capacity}
     * @throws IOException
     *         if the specified stream threw an exception during I/O
     */
    public abstract ByteBuf getBytes(int index, OutputStream out, int length) throws IOException;

    /**
     * Transfers this buffer's data to the specified channel starting at the
     * specified absolute {@code index}.
     * This method does not modify {@code readerIndex} or {@code writerIndex} of
     * this buffer.
     *从当前buf的绝对索引index开始,转移数据到目的聚集字节通道GatheringByteChannel中,
     ,此方法不会修改当前buf的读写索引
     * @param length the maximum number of bytes to transfer
     *
     * @return the actual number of bytes written out to the specified channel
     *
     * @throws IndexOutOfBoundsException
     *         if the specified {@code index} is less than {@code 0} or
     *         if {@code index + length} is greater than
     *            {@code this.capacity}
     * @throws IOException
     *         if the specified channel threw an exception during I/O
     */
    public abstract int getBytes(int index, GatheringByteChannel out, int length) throws IOException;

    /**
     * Transfers this buffer's data starting at the specified absolute {@code index}
     * to the specified channel starting at the given file position.
     * This method does not modify {@code readerIndex} or {@code writerIndex} of
     * this buffer. This method does not modify the channel's position.
     *从当前buf的绝对索引index开始,转移数据到目的文件域FileChannel中,
     此方法不会修改当前buf的读写索引,同时不会修改文件域的位置索引position
     * @param position the file position at which the transfer is to begin
     * @param length the maximum number of bytes to transfer
     *
     * @return the actual number of bytes written out to the specified channel
     *
     * @throws IndexOutOfBoundsException
     *         if the specified {@code index} is less than {@code 0} or
     *         if {@code index + length} is greater than
     *            {@code this.capacity}
     * @throws IOException
     *         if the specified channel threw an exception during I/O
     */
    public abstract int getBytes(int index, FileChannel out, long position, int length) throws IOException;

    /**
     * Gets a {@link CharSequence} with the given length at the given index.
     *从buf的index索引开始,获取给定长度字符序列
     * @param length the length to read
     * @param charset that should be used
     * @return the sequence
     * @throws IndexOutOfBoundsException
     *         if {@code length} is greater than {@code this.readableBytes}
     */
    public abstract CharSequence getCharSequence(int index, int length, Charset charset);


    /**
     * Sets the specified byte at the specified absolute {@code index} in this
     * buffer.  The 24 high-order bits of the specified value are ignored.
     * This method does not modify {@code readerIndex} or {@code writerIndex} of
     * this buffer.
     *从buf的索引index开始,设置特殊的字节,一些特殊值的高24位将会被忽略,不会修改buf的读写索引
     * @throws IndexOutOfBoundsException
     *         if the specified {@code index} is less than {@code 0} or
     *         {@code index + 1} is greater than {@code this.capacity}
     */
    public abstract ByteBuf setByte(int index, int value);

    
    /**
     * Transfers the specified source buffer's data to this buffer starting at
     * the specified absolute {@code index} until the source buffer becomes
     * unreadable.  This method is basically same with
     * {@link #setBytes(int, ByteBuf, int, int)}, except that this
     * method increases the {@code readerIndex} of the source buffer by
     * the number of the transferred bytes while
     * {@link #setBytes(int, ByteBuf, int, int)} does not.
     * This method does not modify {@code readerIndex} or {@code writerIndex} of
     * the source buffer (i.e. {@code this}).
     *从源buf转移数据到当前buf的绝对索引index上,直到源buf不可读。此方法与setBytes(int, ByteBuf, int, int)
     相同,不同的时此方法会增加源buf的索引,而setBytes(int, ByteBuf, int, int)不会。
     此方法不为修改源buf的读写索引
     * @throws IndexOutOfBoundsException
     *         if the specified {@code index} is less than {@code 0} or
     *         if {@code index + src.readableBytes} is greater than
     *            {@code this.capacity}
     */
    public abstract ByteBuf setBytes(int index, ByteBuf src);

    /**
     * Transfers the specified source buffer's data to this buffer starting at
     * the specified absolute {@code index}.  This method is basically same
     * with {@link #setBytes(int, ByteBuf, int, int)}, except that this
     * method increases the {@code readerIndex} of the source buffer by
     * the number of the transferred bytes while
     * {@link #setBytes(int, ByteBuf, int, int)} does not.
     * This method does not modify {@code readerIndex} or {@code writerIndex} of
     * the source buffer (i.e. {@code this}).
     *与上面不同的时,从源buf转移指定长度的数据
     * @param length the number of bytes to transfer
     *
     * @throws IndexOutOfBoundsException
     *         if the specified {@code index} is less than {@code 0},
     *         if {@code index + length} is greater than
     *            {@code this.capacity}, or
     *         if {@code length} is greater than {@code src.readableBytes}
     */
    public abstract ByteBuf setBytes(int index, ByteBuf src, int length);

    /**
     * Transfers the specified source buffer's data to this buffer starting at
     * the specified absolute {@code index}.
     * This method does not modify {@code readerIndex} or {@code writerIndex}
     * of both the source (i.e. {@code this}) and the destination.
     *与上面个方法不同的是,此方法是从源buf的srcIndex索引开始读数据,并且不会修改源buf和
     目的buf的索引。
     * @param srcIndex the first index of the source
     * @param length   the number of bytes to transfer
     *
     * @throws IndexOutOfBoundsException
     *         if the specified {@code index} is less than {@code 0},
     *         if the specified {@code srcIndex} is less than {@code 0},
     *         if {@code index + length} is greater than
     *            {@code this.capacity}, or
     *         if {@code srcIndex + length} is greater than
     *            {@code src.capacity}
     */
    public abstract ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length);

    /**
     * Transfers the specified source array's data to this buffer starting at
     * the specified absolute {@code index}.
     * This method does not modify {@code readerIndex} or {@code writerIndex} of
     * this buffer.
     *转移源字节数组中的数据到当前buf的index位置,不会修改当前buf的索引。
     * @throws IndexOutOfBoundsException
     *         if the specified {@code index} is less than {@code 0} or
     *         if {@code index + src.length} is greater than
     *            {@code this.capacity}
     */
    public abstract ByteBuf setBytes(int index, byte[] src);

    /**
     * Transfers the specified source array's data to this buffer starting at
     * the specified absolute {@code index}.
     * This method does not modify {@code readerIndex} or {@code writerIndex} of
     * this buffer.
     *与上面不同的是此方法是从源buf的srcIndex索引开始读数据,并且字节长度为length
     * @throws IndexOutOfBoundsException
     *         if the specified {@code index} is less than {@code 0},
     *         if the specified {@code srcIndex} is less than {@code 0},
     *         if {@code index + length} is greater than
     *            {@code this.capacity}, or
     *         if {@code srcIndex + length} is greater than {@code src.length}
     */
    public abstract ByteBuf setBytes(int index, byte[] src, int srcIndex, int length);

    /**
     * Transfers the specified source buffer's data to this buffer starting at
     * the specified absolute {@code index} until the source buffer's position
     * reaches its limit.
     * This method does not modify {@code readerIndex} or {@code writerIndex} of
     * this buffer.
     *转移nio ByteBuffer中的数据到当前buf,直到位置索引到达limit位置,此方法不会修改读写索引
     * @throws IndexOutOfBoundsException
     *         if the specified {@code index} is less than {@code 0} or
     *         if {@code index + src.remaining()} is greater than
     *            {@code this.capacity}
     */
    public abstract ByteBuf setBytes(int index, ByteBuffer src);

    /**
     * Transfers the content of the specified source stream to this buffer
     * starting at the specified absolute {@code index}.
     * This method does not modify {@code readerIndex} or {@code writerIndex} of
     * this buffer.
     *转移目的输入流的数据到当前buf,,此方法不会修改读写索引
     * @param length the number of bytes to transfer
     *
     * @return the actual number of bytes read in from the specified channel.
     *         {@code -1} if the specified channel is closed.
     *
     * @throws IndexOutOfBoundsException
     *         if the specified {@code index} is less than {@code 0} or
     *         if {@code index + length} is greater than {@code this.capacity}
     * @throws IOException
     *         if the specified stream threw an exception during I/O
     */
    public abstract int setBytes(int index, InputStream in, int length) throws IOException;

    /**
     * Transfers the content of the specified source channel to this buffer
     * starting at the specified absolute {@code index}.
     * This method does not modify {@code readerIndex} or {@code writerIndex} of
     * this buffer.
     *转移目的分散字节通道的数据到当前buf,,此方法不会修改读写索引
     * @param length the maximum number of bytes to transfer
     *
     * @return the actual number of bytes read in from the specified channel.
     *         {@code -1} if the specified channel is closed.
     *
     * @throws IndexOutOfBoundsException
     *         if the specified {@code index} is less than {@code 0} or
     *         if {@code index + length} is greater than {@code this.capacity}
     * @throws IOException
     *         if the specified channel threw an exception during I/O
     */
    public abstract int setBytes(int index, ScatteringByteChannel in, int length) throws IOException;

    /**
     * Transfers the content of the specified source channel starting at the given file position
     * to this buffer starting at the specified absolute {@code index}.
     * This method does not modify {@code readerIndex} or {@code writerIndex} of
     * this buffer. This method does not modify the channel's position.
     *转移目的文件通道的数据到当前buf,,此方法不会修改读写索引
     * @param position the file position at which the transfer is to begin
     * @param length the maximum number of bytes to transfer
     *
     * @return the actual number of bytes read in from the specified channel.
     *         {@code -1} if the specified channel is closed.
     *
     * @throws IndexOutOfBoundsException
     *         if the specified {@code index} is less than {@code 0} or
     *         if {@code index + length} is greater than {@code this.capacity}
     * @throws IOException
     *         if the specified channel threw an exception during I/O
     */
    public abstract int setBytes(int index, FileChannel in, long position, int length) throws IOException;

    /**
     * Fills this buffer with <tt>NUL (0x00)</tt> starting at the specified
     * absolute {@code index}.
     * This method does not modify {@code readerIndex} or {@code writerIndex} of
     * this buffer.
     *从buf的index位置,填充字节buf为NUL (0x00),此方法不会修改当前buf中的索引位置
     * @param length the number of <tt>NUL</tt>s to write to the buffer
     *
     * @throws IndexOutOfBoundsException
     *         if the specified {@code index} is less than {@code 0} or
     *         if {@code index + length} is greater than {@code this.capacity}
     */
    public abstract ByteBuf setZero(int index, int length);

    /**
     * Writes the specified {@link CharSequence} at the current {@code writerIndex} and increases
     * the {@code writerIndex} by the written bytes.
     *从当前写索引位置开始,写字符序列到当前buf,并更新写索引
     * @param index on which the sequence should be written
     * @param sequence to write
     * @param charset that should be used.
     * @return the written number of bytes.
     * @throws IndexOutOfBoundsException
     *         if {@code this.writableBytes} is not large enough to write the whole sequence
     */
    public abstract int setCharSequence(int index, CharSequence sequence, Charset charset);

  

    /**
     * Gets a byte at the current {@code readerIndex} and increases
     * the {@code readerIndex} by {@code 1} in this buffer.
     * 从buf当前的读索引开始,读取一个字节数据,读索引向前移一位
     * @throws IndexOutOfBoundsException
     *         if {@code this.readableBytes} is less than {@code 1}
     */
    public abstract byte  readByte();

   

    /**
     * Transfers this buffer's data to a newly created buffer starting at
     * the current {@code readerIndex} and increases the {@code readerIndex}
     * by the number of the transferred bytes (= {@code length}).
     * The returned buffer's {@code readerIndex} and {@code writerIndex} are
     * {@code 0} and {@code length} respectively.
     *从当前buf的读索引开始转移length字节数据到新创建的buf中,并增加当前buf的读索引,
     新创建的buf的读索引为0,写索引为length
     * @param length the number of bytes to transfer
     *
     * @return the newly created buffer which contains the transferred bytes
     *
     * @throws IndexOutOfBoundsException
     *         if {@code length} is greater than {@code this.readableBytes}
     */
    public abstract ByteBuf readBytes(int length);

    /**
     * Returns a new slice of this buffer's sub-region starting at the current
     * {@code readerIndex} and increases the {@code readerIndex} by the size
     * of the new slice (= {@code length}).
     返回当前buf的读索引开始,长度为length的字节切片
     * <p>
     * Also be aware that this method will NOT call {@link #retain()} and so the
     * reference count will NOT be increased.
     * 注意此方法不会调用retain方法,索引buf的引用计数器不会变
     * @param length the size of the new slice
     *
     * @return the newly created slice
     *
     * @throws IndexOutOfBoundsException
     *         if {@code length} is greater than {@code this.readableBytes}
     */
    public abstract ByteBuf readSlice(int length);

    /**
     * Returns a new retained slice of this buffer's sub-region starting at the current
     * {@code readerIndex} and increases the {@code readerIndex} by the size
     * of the new slice (= {@code length}).
     * <p>
     * Note that this method returns a {@linkplain #retain() retained} buffer unlike {@link #readSlice(int)}.
     * This method behaves similarly to {@code readSlice(...).retain()} except that this method may return
     * a buffer implementation that produces less garbage.
     *与上面方法不同的时,会增加buf的引用计数器,会产生少量的垃圾
     * @param length the size of the new slice
     *
     * @return the newly created slice
     *
     * @throws IndexOutOfBoundsException
     *         if {@code length} is greater than {@code this.readableBytes}
     */
    public abstract ByteBuf readRetainedSlice(int length);

    /**
     * Transfers this buffer's data to the specified destination starting at
     * the current {@code readerIndex} until the destination becomes
     * non-writable, and increases the {@code readerIndex} by the number of the
     * transferred bytes.  This method is basically same with
     * {@link #readBytes(ByteBuf, int, int)}, except that this method
     * increases the {@code writerIndex} of the destination by the number of
     * the transferred bytes while {@link #readBytes(ByteBuf, int, int)}
     * does not.
     *从当前buf的读索引开始,转移数据到目的buf,直到当前buf不可读,同时更新当前buf的读索引。
     此方法,与#readBytes(ByteBuf, int, int)基本相同,不同的是此方法会增加目的字节buf的写索引,
     而#readBytes(ByteBuf, int, int)不会。
     * @throws IndexOutOfBoundsException
     *         if {@code dst.writableBytes} is greater than
     *            {@code this.readableBytes}
     */
    public abstract ByteBuf readBytes(ByteBuf dst);

    /**
     * Transfers this buffer's data to the specified destination starting at
     * the current {@code readerIndex} and increases the {@code readerIndex}
     * by the number of the transferred bytes (= {@code length}).  This method
     * is basically same with {@link #readBytes(ByteBuf, int, int)},
     * except that this method increases the {@code writerIndex} of the
     * destination by the number of the transferred bytes (= {@code length})
     * while {@link #readBytes(ByteBuf, int, int)} does not.
     *与上面方法不同到的是,从当前buf读取指定长度的字节数据
     * @throws IndexOutOfBoundsException
     *         if {@code length} is greater than {@code this.readableBytes} or
     *         if {@code length} is greater than {@code dst.writableBytes}
     */
    public abstract ByteBuf readBytes(ByteBuf dst, int length);

    /**
     * Transfers this buffer's data to the specified destination starting at
     * the current {@code readerIndex} and increases the {@code readerIndex}
     * by the number of the transferred bytes (= {@code length}).
     *此方法,与上面方法不同的是,将当前buf的数据放到目的buf的dstIndex位置,同时,
     此方法不会修改目的buf的写索引
     * @param dstIndex the first index of the destination
     * @param length   the number of bytes to transfer
     *
     * @throws IndexOutOfBoundsException
     *         if the specified {@code dstIndex} is less than {@code 0},
     *         if {@code length} is greater than {@code this.readableBytes}, or
     *         if {@code dstIndex + length} is greater than
     *            {@code dst.capacity}
     */
    public abstract ByteBuf readBytes(ByteBuf dst, int dstIndex, int length);

    /**
     * Transfers this buffer's data to the specified destination starting at
     * the current {@code readerIndex} and increases the {@code readerIndex}
     * by the number of the transferred bytes (= {@code dst.length}).
     *从当前buf的读索引开始,转移数据到目的字节数组中
     * @throws IndexOutOfBoundsException
     *         if {@code dst.length} is greater than {@code this.readableBytes}
     */
    public abstract ByteBuf readBytes(byte[] dst);

    /**
     * Transfers this buffer's data to the specified destination starting at
     * the current {@code readerIndex} and increases the {@code readerIndex}
     * by the number of the transferred bytes (= {@code length}).
     *与上面方法不同的是,转移字节长度为length,并方法目的字节数组的dstIndex上
     * @param dstIndex the first index of the destination
     * @param length   the number of bytes to transfer
     *
     * @throws IndexOutOfBoundsException
     *         if the specified {@code dstIndex} is less than {@code 0},
     *         if {@code length} is greater than {@code this.readableBytes}, or
     *         if {@code dstIndex + length} is greater than {@code dst.length}
     */
    public abstract ByteBuf readBytes(byte[] dst, int dstIndex, int length);

    /**
     * Transfers this buffer's data to the specified destination starting at
     * the current {@code readerIndex} until the destination's position
     * reaches its limit, and increases the {@code readerIndex} by the
     * number of the transferred bytes.
     *从当前buf的读索引开始,转移数据到java nio ByteBuffer中,同时会更新当前buf的读索引
     * @throws IndexOutOfBoundsException
     *         if {@code dst.remaining()} is greater than
     *            {@code this.readableBytes}
     */
    public abstract ByteBuf readBytes(ByteBuffer dst);

    /**
     * Transfers this buffer's data to the specified stream starting at the
     * current {@code readerIndex}.
     *从当前buf的读索引开始,转移数据到输出流OutputStream中
     * @param length the number of bytes to transfer
     *
     * @throws IndexOutOfBoundsException
     *         if {@code length} is greater than {@code this.readableBytes}
     * @throws IOException
     *         if the specified stream threw an exception during I/O
     */
    public abstract ByteBuf readBytes(OutputStream out, int length) throws IOException;

    /**
     * Transfers this buffer's data to the specified stream starting at the
     * current {@code readerIndex}.
     *从当前buf的读索引开始,转移数据到目的聚集通道中
     * @param length the maximum number of bytes to transfer
     *
     * @return the actual number of bytes written out to the specified channel
     *
     * @throws IndexOutOfBoundsException
     *         if {@code length} is greater than {@code this.readableBytes}
     * @throws IOException
     *         if the specified channel threw an exception during I/O
     */
    public abstract int readBytes(GatheringByteChannel out, int length) throws IOException;

    /**
     * Gets a {@link CharSequence} with the given length at the current {@code readerIndex}
     * and increases the {@code readerIndex} by the given length.
     *从当前buf的读索引开始,转移length长度的字节数据到目的字符序列中,同时会更新当前buf的读索引
     * @param length the length to read
     * @param charset that should be used
     * @return the sequence
     * @throws IndexOutOfBoundsException
     *         if {@code length} is greater than {@code this.readableBytes}
     */
    public abstract CharSequence readCharSequence(int length, Charset charset);

    /**
     * Transfers this buffer's data starting at the current {@code readerIndex}
     * to the specified channel starting at the given file position.
     * This method does not modify the channel's position.
     *从当前buf的读索引开始,转移数据到目的文件通道中,不会修改文件通道的位置
     * @param position the file position at which the transfer is to begin
     * @param length the maximum number of bytes to transfer
     *
     * @return the actual number of bytes written out to the specified channel
     *
     * @throws IndexOutOfBoundsException
     *         if {@code length} is greater than {@code this.readableBytes}
     * @throws IOException
     *         if the specified channel threw an exception during I/O
     */
    public abstract int readBytes(FileChannel out, long position, int length) throws IOException;

    /**
     * Increases the current {@code readerIndex} by the specified
     * {@code length} in this buffer.
     *增加读索引位置length长度,向前移动length位置
     * @throws IndexOutOfBoundsException
     *         if {@code length} is greater than {@code this.readableBytes}
     */
    public abstract ByteBuf skipBytes(int length);

    /**
     * Sets the specified boolean at the current {@code writerIndex}
     * and increases the {@code writerIndex} by {@code 1} in this buffer.
     * 从buf当前写索引位置写一个布尔值,写索引向前移一位
     * @throws IndexOutOfBoundsException
     *         if {@code this.writableBytes} is less than {@code 1}
     */
    public abstract ByteBuf writeBoolean(boolean value);

    /**
     * Sets the specified byte at the current {@code writerIndex}
     * and increases the {@code writerIndex} by {@code 1} in this buffer.
     * The 24 high-order bits of the specified value are ignored.
     * 从buf当前写索引位置写一个字节,写索引向前移一位。
     一些特殊值的高24位将会被忽略
     * @throws IndexOutOfBoundsException
     *         if {@code this.writableBytes} is less than {@code 1}
     */
    public abstract ByteBuf writeByte(int value);

    

    /**
     * Transfers the specified source buffer's data to this buffer starting at
     * the current {@code writerIndex} until the source buffer becomes
     * unreadable, and increases the {@code writerIndex} by the number of
     * the transferred bytes.  This method is basically same with
     * {@link #writeBytes(ByteBuf, int, int)}, except that this method
     * increases the {@code readerIndex} of the source buffer by the number of
     * the transferred bytes while {@link #writeBytes(ByteBuf, int, int)}
     * does not.
     *从当前buf写索引开始,转移源buf中的数据到当前buf的中,直到源buf不可读,同时更新当前buf的写索引,
     此方法与#writeBytes(ByteBuf, int, int)基本相同,除了此方法回修改源buf的读索引,而#writeBytes(ByteBuf, int, int)
     不会。

     * @throws IndexOutOfBoundsException
     *         if {@code src.readableBytes} is greater than
     *            {@code this.writableBytes}
     */
    public abstract ByteBuf writeBytes(ByteBuf src);

    /**
     * Transfers the specified source buffer's data to this buffer starting at
     * the current {@code writerIndex} and increases the {@code writerIndex}
     * by the number of the transferred bytes (= {@code length}).  This method
     * is basically same with {@link #writeBytes(ByteBuf, int, int)},
     * except that this method increases the {@code readerIndex} of the source
     * buffer by the number of the transferred bytes (= {@code length}) while
     * {@link #writeBytes(ByteBuf, int, int)} does not.
     * 与上面方法不同的时,限制源buf转移数据的长度
     * @param length the number of bytes to transfer
     *
     * @throws IndexOutOfBoundsException
     *         if {@code length} is greater than {@code this.writableBytes} or
     *         if {@code length} is greater then {@code src.readableBytes}
     */
    public abstract ByteBuf writeBytes(ByteBuf src, int length);

    /**
     * Transfers the specified source buffer's data to this buffer starting at
     * the current {@code writerIndex} and increases the {@code writerIndex}
     * by the number of the transferred bytes (= {@code length}).
     * 与上面方法不同的是,转移数据从指定索引开始srcIndex
     * @param srcIndex the first index of the source
     * @param length   the number of bytes to transfer
     *
     * @throws IndexOutOfBoundsException
     *         if the specified {@code srcIndex} is less than {@code 0},
     *         if {@code srcIndex + length} is greater than
     *            {@code src.capacity}, or
     *         if {@code length} is greater than {@code this.writableBytes}
     */
    public abstract ByteBuf writeBytes(ByteBuf src, int srcIndex, int length);

    /**
     * Transfers the specified source array's data to this buffer starting at
     * the current {@code writerIndex} and increases the {@code writerIndex}
     * by the number of the transferred bytes (= {@code src.length}).
     * 写字节数组中的数据到当前buf,并更新当前buf的写索引
     * @throws IndexOutOfBoundsException
     *         if {@code src.length} is greater than {@code this.writableBytes}
     */
    public abstract ByteBuf writeBytes(byte[] src);

    /**
     * Transfers the specified source array's data to this buffer starting at
     * the current {@code writerIndex} and increases the {@code writerIndex}
     * by the number of the transferred bytes (= {@code length}).
     *与上面方法不同的时,限定了字节数组的开始索引
     * @param srcIndex the first index of the source
     * @param length   the number of bytes to transfer
     *
     * @throws IndexOutOfBoundsException
     *         if the specified {@code srcIndex} is less than {@code 0},
     *         if {@code srcIndex + length} is greater than
     *            {@code src.length}, or
     *         if {@code length} is greater than {@code this.writableBytes}
     */
    public abstract ByteBuf writeBytes(byte[] src, int srcIndex, int length);

    /**
     * Transfers the specified source buffer's data to this buffer starting at
     * the current {@code writerIndex} until the source buffer's position
     * reaches its limit, and increases the {@code writerIndex} by the
     * number of the transferred bytes.
     写java nio ByteBuffer中的数据到当前buf,直到ByteBuffer的位置索引到limit位置,同时更新写索引
     *
     * @throws IndexOutOfBoundsException
     *         if {@code src.remaining()} is greater than
     *            {@code this.writableBytes}
     */
    public abstract ByteBuf writeBytes(ByteBuffer src);

    /**
     * Transfers the content of the specified stream to this buffer
     * starting at the current {@code writerIndex} and increases the
     * {@code writerIndex} by the number of the transferred bytes.
     *写输入流InputStream中的length个字节数据到当前buf,同时更新写索引
     * @param length the number of bytes to transfer
     *
     * @return the actual number of bytes read in from the specified stream
     *
     * @throws IndexOutOfBoundsException
     *         if {@code length} is greater than {@code this.writableBytes}
     * @throws IOException
     *         if the specified stream threw an exception during I/O
     */
    public abstract int  writeBytes(InputStream in, int length) throws IOException;

    /**
     * Transfers the content of the specified channel to this buffer
     * starting at the current {@code writerIndex} and increases the
     * {@code writerIndex} by the number of the transferred bytes.
     *写分散字节通道ScatteringByteChannel中的length个字节数据到当前buf,同时更新写索引
     * @param length the maximum number of bytes to transfer
     *
     * @return the actual number of bytes read in from the specified channel
     *
     * @throws IndexOutOfBoundsException
     *         if {@code length} is greater than {@code this.writableBytes}
     * @throws IOException
     *         if the specified channel threw an exception during I/O
     */
    public abstract int writeBytes(ScatteringByteChannel in, int length) throws IOException;

    /**
     * Transfers the content of the specified channel starting at the given file position
     * to this buffer starting at the current {@code writerIndex} and increases the
     * {@code writerIndex} by the number of the transferred bytes.
     * This method does not modify the channel's position.
     *写文件FileChannel中的length个字节数据到当前buf,同时更新写索引,不会修改通道的位置索引
     * @param position the file position at which the transfer is to begin
     * @param length the maximum number of bytes to transfer
     *
     * @return the actual number of bytes read in from the specified channel
     *
     * @throws IndexOutOfBoundsException
     *         if {@code length} is greater than {@code this.writableBytes}
     * @throws IOException
     *         if the specified channel threw an exception during I/O
     */
    public abstract int writeBytes(FileChannel in, long position, int length) throws IOException;

    /**
     * Fills this buffer with <tt>NUL (0x00)</tt> starting at the current
     * {@code writerIndex} and increases the {@code writerIndex} by the
     * specified {@code length}.
     *从当前写索引开始,填充length个NUL (0x00)
     * @param length the number of <tt>NUL</tt>s to write to the buffer
     *
     * @throws IndexOutOfBoundsException
     *         if {@code length} is greater than {@code this.writableBytes}
     */
    public abstract ByteBuf writeZero(int length);

    /**
     * Writes the specified {@link CharSequence} at the current {@code writerIndex} and increases
     * the {@code writerIndex} by the written bytes.
     * in this buffer.
     *从当前写索引,写字符序列到当前buf
     * @param sequence to write
     * @param charset that should be used
     * @return the written number of bytes
     * @throws IndexOutOfBoundsException
     *         if {@code this.writableBytes} is not large enough to write the whole sequence
     */
    public abstract int writeCharSequence(CharSequence sequence, Charset charset);

   
  
    /**
     * Returns a copy of this buffer's readable bytes.  Modifying the content
     * of the returned buffer or this buffer does not affect each other at all.
     * This method is identical to {@code buf.copy(buf.readerIndex(), buf.readableBytes())}.
     * This method does not modify {@code readerIndex} or {@code writerIndex} of
     * this buffer.
     返回当前buf 可读字节的拷贝。修改返回的copy buf,不会影响当前buf。此方法与
     buf.copy(buf.readerIndex(), buf.readableBytes())方法相同,不会修改读写索引
     */
    public abstract ByteBuf copy();

    /**
     * Returns a copy of this buffer's sub-region.  Modifying the content of
     * the returned buffer or this buffer does not affect each other at all.
     * This method does not modify {@code readerIndex} or {@code writerIndex} of
     * this buffer.
     此方法与上面方法,不同的是,限定了读数据开始索引和读取字节的长度
     */
    public abstract ByteBuf copy(int index, int length);

    /**
     * Returns a slice of this buffer's readable bytes. Modifying the content
     * of the returned buffer or this buffer affects each other's content
     * while they maintain separate indexes and marks.  This method is
     * identical to {@code buf.slice(buf.readerIndex(), buf.readableBytes())}.
     * This method does not modify {@code readerIndex} or {@code writerIndex} of
     * this buffer.
     返回当前buf的可读字节数据的切片slice,当他们维护各自的索引和标记时,
     修改返回的切片buf或当前buf,会相互影响buf数据,此方法等同于
     buf.slice(buf.readerIndex(), buf.readableBytes()),此方法不会修改读写索引

     * <p>
     * Also be aware that this method will NOT call {@link #retain()} and so the
     * reference count will NOT be increased.
     注意,此方法不会调用retain方法,即不会增加buf的引用计数器
     */
    public abstract ByteBuf slice();

    /**
     * Returns a slice of this buffer's sub-region. Modifying the content of
     * the returned buffer or this buffer affects each other's content while
     * they maintain separate indexes and marks.
     * This method does not modify {@code readerIndex} or {@code writerIndex} of
     * this buffer.
     此方法与上面方法,不同的是,限定了切片数据开始索引和字节的长度
     * <p>
     * Also be aware that this method will NOT call {@link #retain()} and so the
     * reference count will NOT be increased.
     */
    public abstract ByteBuf slice(int index, int length);

    /**
     * Returns a retained slice of this buffer's readable bytes. Modifying the content
     * of the returned buffer or this buffer affects each other's content
     * while they maintain separate indexes and marks.  This method is
     * identical to {@code buf.slice(buf.readerIndex(), buf.readableBytes())}.
     * This method does not modify {@code readerIndex} or {@code writerIndex} of
     * this buffer.
     * <p>
     * Note that this method returns a {@linkplain #retain() retained} buffer unlike {@link #slice()}.
     * This method behaves similarly to {@code slice().retain()} except that this method may return
     * a buffer implementation that produces less garbage.
     与#slice方法不同的是,会调用retain方法,即增加buf的引用计数器,同时可能会产生一些内存垃圾
     */
    public abstract ByteBuf retainedSlice();


    /**
     * Returns a retained slice of this buffer's sub-region. Modifying the content of
     * the returned buffer or this buffer affects each other's content while
     * they maintain separate indexes and marks.
     * This method does not modify {@code readerIndex} or {@code writerIndex} of
     * this buffer.
     * <p>
     * Note that this method returns a {@linkplain #retain() retained} buffer unlike {@link #slice(int, int)}.
     * This method behaves similarly to {@code slice(...).retain()} except that this method may return
     * a buffer implementation that produces less garbage.
     此方法与上面方法,不同的是,限定了切片数据开始索引和字节的长度
     */
    public abstract ByteBuf retainedSlice(int index, int length);

    /**
     * Returns a buffer which shares the whole region of this buffer.
     * Modifying the content of the returned buffer or this buffer affects
     * each other's content while they maintain separate indexes and marks.
     * This method does not modify {@code readerIndex} or {@code writerIndex} of
     * this buffer.
     返回buf的整个共享域,当他们维护各自的索引和标记时,
     修改返回的buf或当前buf,会相互影响buf数据,此方法不会修改读写索引
     * <p>
     * The reader and writer marks will not be duplicated. Also be aware that this method will
     * NOT call {@link #retain()} and so the reference count will NOT be increased.
     * @return A buffer whose readable content is equivalent to the buffer returned by {@link #slice()}.
     * However this buffer will share the capacity of the underlying buffer, and therefore allows access to all of the
     * underlying content if necessary.
     读写标记不会复制。同时此方法不会调用retain方法,即不会增加buf的引用计数器,
     返回的buf的可读内容相当于#slice方法返回的buf。不同的是,此方法返回的buf与底层buf共享容量,
     因此如果需要,运行方法底层的数据内容
     */
    public abstract ByteBuf duplicate();

    /**
     * Returns a retained buffer which shares the whole region of this buffer.
     * Modifying the content of the returned buffer or this buffer affects
     * each other's content while they maintain separate indexes and marks.
     * This method is identical to {@code buf.slice(0, buf.capacity())}.
     * This method does not modify {@code readerIndex} or {@code writerIndex} of
     * this buffer.
     * <p>
     * Note that this method returns a {@linkplain #retain() retained} buffer unlike {@link #slice(int, int)}.
     * This method behaves similarly to {@code duplicate().retain()} except that this method may return
     * a buffer implementation that produces less garbage.
     与上述方法不同的是,会调用retain方法,即增加buf的引用计数器,同时可能会产生一些内存垃圾
     */
    public abstract ByteBuf retainedDuplicate();

    /**
     * Returns the maximum number of NIO {@link ByteBuffer}s that consist this buffer.  Note that {@link #nioBuffers()}
     * or {@link #nioBuffers(int, int)} might return a less number of {@link ByteBuffer}s.
     *返回包含当前buf的最大java nio ByteBuffer数量。注意#nioBuffers和#nioBuffers(int, int)方法,可能
     返回更少数量的ByteBuffer
     * @return {@code -1} if this buffer has no underlying {@link ByteBuffer}.
     *         the number of the underlying {@link ByteBuffer}s if this buffer has at least one underlying
     *         {@link ByteBuffer}.  Note that this method does not return {@code 0} to avoid confusion.
     * 如果当前buf没有底层ByteBuffer,则返回-1。如果当前buf至少有一个ByteBuffer,则返回数量。注意为了避免
     冲突,此方法不会返回0。
     * @see #nioBuffer()
     * @see #nioBuffer(int, int)
     * @see #nioBuffers()
     * @see #nioBuffers(int, int)
     */
    public abstract int nioBufferCount();

    /**
     * Exposes this buffer's readable bytes as an NIO {@link ByteBuffer}.  The returned buffer
     * shares the content with this buffer, while changing the position and limit of the returned
     * NIO buffer does not affect the indexes and marks of this buffer.  This method is identical
     * to {@code buf.nioBuffer(buf.readerIndex(), buf.readableBytes())}.  This method does not
     * modify {@code readerIndex} or {@code writerIndex} of this buffer.  Please note that the
     * returned NIO buffer will not see the changes of this buffer if this buffer is a dynamic
     * buffer and it adjusted its capacity.
     * 暴露当前buf的可读数据到一个java nio ByteBuffer中。返回的java nio ByteBuffer与当前buf共享数据,
     但修改java nio ByteBuffer的位置和limit,不会修改当前buf的索引和标记。
     此方法与buf.nioBuffer(buf.readerIndex(), buf.readableBytes()相同。此方法不会修改当前buf的读写索引。
     如果当前buf是一个动态的buf,调整buf容量时,java nio ByteBuffer 是看不到容量的改变的。
     * @throws UnsupportedOperationException
     *         if this buffer cannot create a {@link ByteBuffer} that shares the content with itself
     *
     * @see #nioBufferCount()
     * @see #nioBuffers()
     * @see #nioBuffers(int, int)
     */
    public abstract ByteBuffer nioBuffer();

    /**
     * Exposes this buffer's sub-region as an NIO {@link ByteBuffer}.  The returned buffer
     * shares the content with this buffer, while changing the position and limit of the returned
     * NIO buffer does not affect the indexes and marks of this buffer.  This method does not
     * modify {@code readerIndex} or {@code writerIndex} of this buffer.  Please note that the
     * returned NIO buffer will not see the changes of this buffer if this buffer is a dynamic
     * buffer and it adjusted its capacity.
     *与上面不同的时,限定了共享region的开始索引和数据长度
     * @throws UnsupportedOperationException
     *         if this buffer cannot create a {@link ByteBuffer} that shares the content with itself
     *
     * @see #nioBufferCount()
     * @see #nioBuffers()
     * @see #nioBuffers(int, int)
     */
    public abstract ByteBuffer nioBuffer(int index, int length);

    /**
     * Internal use only: Exposes the internal NIO buffer.
     内部使用,暴露一个内部的nio buf
     */
    public abstract ByteBuffer internalNioBuffer(int index, int length);

    /**
     * Exposes this buffer's readable bytes as an NIO {@link ByteBuffer}'s.  The returned buffer
     * shares the content with this buffer, while changing the position and limit of the returned
     * NIO buffer does not affect the indexes and marks of this buffer. This method does not
     * modify {@code readerIndex} or {@code writerIndex} of this buffer.  Please note that the
     * returned NIO buffer will not see the changes of this buffer if this buffer is a dynamic
     * buffer and it adjusted its capacity.
     *
     *与#nioBuffer方法不同的是返回的是一个nio buf数组
     * @throws UnsupportedOperationException
     *         if this buffer cannot create a {@link ByteBuffer} that shares the content with itself
     *
     * @see #nioBufferCount()
     * @see #nioBuffer()
     * @see #nioBuffer(int, int)
     */
    public abstract ByteBuffer[] nioBuffers();

    /**
     * Exposes this buffer's bytes as an NIO {@link ByteBuffer}'s for the specified index and length
     * The returned buffer shares the content with this buffer, while changing the position and limit
     * of the returned NIO buffer does not affect the indexes and marks of this buffer. This method does
     * not modify {@code readerIndex} or {@code writerIndex} of this buffer.  Please note that the
     * returned NIO buffer will not see the changes of this buffer if this buffer is a dynamic
     * buffer and it adjusted its capacity.
     *与上面不同的时,限定了共享region的开始索引和数据长度
     * @throws UnsupportedOperationException
     *         if this buffer cannot create a {@link ByteBuffer} that shares the content with itself
     *
     * @see #nioBufferCount()
     * @see #nioBuffer()
     * @see #nioBuffer(int, int)
     */
    public abstract ByteBuffer[] nioBuffers(int index, int length);

    /**
     * Returns {@code true} if and only if this buffer has a backing byte array.
     * If this method returns true, you can safely call {@link #array()} and
     * {@link #arrayOffset()}.
     当前仅当,buf由于有一个backing 字节数组,返回true。如果方法返回true,则可以调用
     #array() 和 #arrayOffset()方法.
     */
    public abstract boolean hasArray();

    /**
     * Returns the backing byte array of this buffer.
     *返回当前buf的backing字节数组
     * @throws UnsupportedOperationException
     *         if there no accessible backing byte array
     */
    public abstract byte[] array();

    /**
     * Returns the offset of the first byte within the backing byte array of
     * this buffer.
     *返回当前buf backing数组第一个字节在buf中的位置
     * @throws UnsupportedOperationException
     *         if there no accessible backing byte array
     */
    public abstract int arrayOffset();

    /**
     * Returns {@code true} if and only if this buffer has a reference to the low-level memory address that points
     * to the backing data.
     当且仅当,当前buf有一个指向backing数据的低位内存地址引用时,返回true
     */
    public abstract boolean hasMemoryAddress();

    /**
     * Returns the low-level memory address that point to the first byte of ths backing data.
     * 返回buf中第一个字节的低位内存地址
     * @throws UnsupportedOperationException
     *         if this buffer does not support accessing the low-level memory address
     */
    public abstract long memoryAddress();

    /**
     * Decodes this buffer's readable bytes into a string with the specified
     * character set name.  This method is identical to
     * {@code buf.toString(buf.readerIndex(), buf.readableBytes(), charsetName)}.
     * This method does not modify {@code readerIndex} or {@code writerIndex} of
     * this buffer.
     *解码可读字节数据为,更定字符编码的字符串,此方法相当与
     buf.toString(buf.readerIndex(), buf.readableBytes(), charsetName),
     此方法不会修改读写索引。
     * @throws UnsupportedCharsetException
     *         if the specified character set name is not supported by the
     *         current VM
     */
    public abstract String toString(Charset charset);

    /**
     * Decodes this buffer's sub-region into a string with the specified
     * character set.  This method does not modify {@code readerIndex} or
     * {@code writerIndex} of this buffer.
     此方法与上面方法,不同的是,限定了buf数据开始索引和字节的长度
     */
    public abstract String toString(int index, int length, Charset charset);

    /**
     * Returns a hash code which was calculated from the content of this
     * buffer.  If there's a byte array which is
     * {@linkplain #equals(Object) equal to} this array, both arrays should
     * return the same value.
     返回buf内容的hash code。如果buf的字节数组相等,则返回相同hash code
     */
    @Override
    public abstract int hashCode();

    /**
     * Determines if the content of the specified buffer is identical to the
     * content of this array.  'Identical' here means:
     * [list]
     * [*]the size of the contents of the two buffers are same and

     * [*]every single byte of the content of the two buffers are same.

     * [/list]
     * Please note that it does not compare {@link #readerIndex()} nor
     * {@link #writerIndex()}.  This method also returns {@code false} for
     * {@code null} and an object which is not an instance of
     * {@link ByteBuf} type.
     判断对象是否想定,当且仅当两个buf中的所有的字节相等,则对象相等,不比较索引,
     如果对象不是字节buf,则返回false
     */
    @Override
    public abstract boolean equals(Object obj);

    /**
     * Compares the content of the specified buffer to the content of this
     * buffer. Comparison is performed in the same manner with the string
     * comparison functions of various languages such as {@code strcmp},
     * {@code memcmp} and {@link String#compareTo(String)}.
     比较buf,以字符串的比较形式
     */
    @Override
    public abstract int compareTo(ByteBuf buffer);

    /**
     * Returns the string representation of this buffer.  This method does not
     * necessarily return the whole content of the buffer but returns
     * the values of the key properties such as {@link #readerIndex()},
     * {@link #writerIndex()} and {@link #capacity()}.
     返回buf所表示的字符串,从读索引到写索引位置
     */
    @Override
    public abstract String toString();
    //增加字节buf引用计数器,增量为increment
    @Override
    public abstract ByteBuf retain(int increment);
    //自增字节buf引用计数器
    @Override
    public abstract ByteBuf retain();

    @Override 
    public abstract ByteBuf touch();
    //调试时,记录buf操作的相关信息,以便分析内存泄漏问题
    @Override
    public abstract ByteBuf touch(Object hint);
}



总结:


对象引用计数器ReferenceCounted,主要记录对象的引用数量,当引用数量为0时,表示可以回收对象,在调试模式下,如果发现对象出现内存泄漏,可以用touch方法记录操作的相关信息,通过ResourceLeakDetector获取操作的相关信息,以便分析内存泄漏的原因。

字节缓存ByteBuf继承了对象引用计数器ReferenceCounted,拥有一个最大容量限制,如果用户尝试用 #capacity(int)和 #ensureWritable(int)方法,增加buf容量超过最大容量,将会抛出非法参数异常;字节buf有两个索引,一个为读索引readerIndex,一个为写索引writerIndex,读索引不能大于写索引,写索引不能小于读索引,buf可读字节数为writerIndex - readerIndex,buf可写字节数为capacity - writerIndex,buf可写的最大字节数为maxCapacity - writerIndex;

可以使用markReader/WriterIndex标记当前buf读写索引位置,resetReader/WriterIndex方法可以重回先前标记的索引位置;

当内存空间负载过度时,我们可以使用discardReadBytes丢弃一些数据,以节省空间;

我们可以使用ensureWritable检测当buf是否有足够的空间写数据;

提供了getBytes方法,可以将buf中的数据转移到目的ByteBuf,Byte数组,Nio字节buf ByteBuffer,OutputStream,聚集字节通道
GatheringByteChannel和文件通道FileChannel中,这些方法不会修改当前buf读写索引,具体是否修改目的对象索引或位置,见java doc 描述。

提供了setBytes方法,可以将源ByteBuf,Byte数组,Nio字节buf ByteBuffer,InputputStream,分散字节通道ScatteringByteChannel和文件通道FileChannel中的数据转移到当前buf中,这些方法不会修改当前buf的读写索引,至于源对象索引或位置,见java doc 描述。

提供了readBytes方法,可以将buf中的数据转移到目的ByteBuf,Byte数组,Nio字节buf ByteBuffer,OutputStream,聚集字节通道GatheringByteChannel和文件通道FileChannel中,这些方法具体会会修改当前buf读索引,至于会不会修改源对象索引或位置,见java doc 描述。

提供了writeBytes方法,可以将源ByteBuf,Byte数组,Nio字节buf ByteBuffer,
InputputStream,分散字节通道ScatteringByteChannel和文件通道FileChannel中的数据写到当前buf中,这些方法会修改当前buf的写索引,至于会不会修改源对象索引或位置,见java
doc 描述。


set*原始类型方法不会修改读写索引;
get*原始类型方法不会修改读写索引;

write*原始类型方法会修改写索引;
read*原始类型方法,会修改读索引;

字节buf中的set/get*方法不会修改当前buf的读写索引,而write*修改写索引,read*会修改读索引;

提供了copy,slice和retainSlice,duplicate和retainedDuplicate方法,用于拷贝,切割,复制当前buf数据,retained*方法会增加buf的引用计数器;

提供nioBuffer和nioBuffers方法,用于包装当前buf可读数据为java nio ByteBuffer和ByteBuffer数组。


附:

下面是字节buf的get*原始类型方法的定义,简单看一下:
下面的方法不会修改读写索引
 /**
 * Gets a boolean at the specified absolute (@code index) in this buffer.
 * This method does not modify the {@code readerIndex} or {@code writerIndex}
 * of this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if the specified {@code index} is less than {@code 0} or
 *         {@code index + 1} is greater than {@code this.capacity}
 */
public abstract boolean getBoolean(int index);
/**
 * Gets an unsigned byte at the specified absolute {@code index} in this
 * buffer.  This method does not modify {@code readerIndex} or
 * {@code writerIndex} of this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if the specified {@code index} is less than {@code 0} or
 *         {@code index + 1} is greater than {@code this.capacity}
 */
public abstract short getUnsignedByte(int index);

/**
 * Gets a 16-bit short integer at the specified absolute {@code index} in
 * this buffer.  This method does not modify {@code readerIndex} or
 * {@code writerIndex} of this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if the specified {@code index} is less than {@code 0} or
 *         {@code index + 2} is greater than {@code this.capacity}
 */
public abstract short getShort(int index);

/**
 * Gets a 16-bit short integer at the specified absolute {@code index} in
 * this buffer in Little Endian Byte Order. This method does not modify
 * {@code readerIndex} or {@code writerIndex} of this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if the specified {@code index} is less than {@code 0} or
 *         {@code index + 2} is greater than {@code this.capacity}
 */
public abstract short getShortLE(int index);

/**
 * Gets an unsigned 16-bit short integer at the specified absolute
 * {@code index} in this buffer.  This method does not modify
 * {@code readerIndex} or {@code writerIndex} of this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if the specified {@code index} is less than {@code 0} or
 *         {@code index + 2} is greater than {@code this.capacity}
 */
public abstract int getUnsignedShort(int index);

/**
 * Gets an unsigned 16-bit short integer at the specified absolute
 * {@code index} in this buffer in Little Endian Byte Order.
 * This method does not modify {@code readerIndex} or
 * {@code writerIndex} of this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if the specified {@code index} is less than {@code 0} or
 *         {@code index + 2} is greater than {@code this.capacity}
 */
public abstract int getUnsignedShortLE(int index);

/**
 * Gets a 24-bit medium integer at the specified absolute {@code index} in
 * this buffer.  This method does not modify {@code readerIndex} or
 * {@code writerIndex} of this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if the specified {@code index} is less than {@code 0} or
 *         {@code index + 3} is greater than {@code this.capacity}
 */
public abstract int   getMedium(int index);

/**
 * Gets a 24-bit medium integer at the specified absolute {@code index} in
 * this buffer in the Little Endian Byte Order. This method does not
 * modify {@code readerIndex} or {@code writerIndex} of this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if the specified {@code index} is less than {@code 0} or
 *         {@code index + 3} is greater than {@code this.capacity}
 */
public abstract int getMediumLE(int index);

/**
 * Gets an unsigned 24-bit medium integer at the specified absolute
 * {@code index} in this buffer.  This method does not modify
 * {@code readerIndex} or {@code writerIndex} of this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if the specified {@code index} is less than {@code 0} or
 *         {@code index + 3} is greater than {@code this.capacity}
 */
public abstract int   getUnsignedMedium(int index);

/**
 * Gets an unsigned 24-bit medium integer at the specified absolute
 * {@code index} in this buffer in Little Endian Byte Order.
 * This method does not modify {@code readerIndex} or
 * {@code writerIndex} of this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if the specified {@code index} is less than {@code 0} or
 *         {@code index + 3} is greater than {@code this.capacity}
 */
public abstract int   getUnsignedMediumLE(int index);

/**
 * Gets a 32-bit integer at the specified absolute {@code index} in
 * this buffer.  This method does not modify {@code readerIndex} or
 * {@code writerIndex} of this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if the specified {@code index} is less than {@code 0} or
 *         {@code index + 4} is greater than {@code this.capacity}
 */
public abstract int   getInt(int index);

/**
 * Gets a 32-bit integer at the specified absolute {@code index} in
 * this buffer with Little Endian Byte Order. This method does not
 * modify {@code readerIndex} or {@code writerIndex} of this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if the specified {@code index} is less than {@code 0} or
 *         {@code index + 4} is greater than {@code this.capacity}
 */
public abstract int   getIntLE(int index);

/**
 * Gets an unsigned 32-bit integer at the specified absolute {@code index}
 * in this buffer.  This method does not modify {@code readerIndex} or
 * {@code writerIndex} of this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if the specified {@code index} is less than {@code 0} or
 *         {@code index + 4} is greater than {@code this.capacity}
 */
public abstract long  getUnsignedInt(int index);

/**
 * Gets an unsigned 32-bit integer at the specified absolute {@code index}
 * in this buffer in Little Endian Byte Order. This method does not
 * modify {@code readerIndex} or {@code writerIndex} of this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if the specified {@code index} is less than {@code 0} or
 *         {@code index + 4} is greater than {@code this.capacity}
 */
public abstract long  getUnsignedIntLE(int index);

/**
 * Gets a 64-bit long integer at the specified absolute {@code index} in
 * this buffer.  This method does not modify {@code readerIndex} or
 * {@code writerIndex} of this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if the specified {@code index} is less than {@code 0} or
 *         {@code index + 8} is greater than {@code this.capacity}
 */
public abstract long  getLong(int index);

/**
 * Gets a 64-bit long integer at the specified absolute {@code index} in
 * this buffer in Little Endian Byte Order. This method does not
 * modify {@code readerIndex} or {@code writerIndex} of this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if the specified {@code index} is less than {@code 0} or
 *         {@code index + 8} is greater than {@code this.capacity}
 */
public abstract long  getLongLE(int index);

/**
 * Gets a 2-byte UTF-16 character at the specified absolute
 * {@code index} in this buffer.  This method does not modify
 * {@code readerIndex} or {@code writerIndex} of this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if the specified {@code index} is less than {@code 0} or
 *         {@code index + 2} is greater than {@code this.capacity}
 */
public abstract char  getChar(int index);

/**
 * Gets a 32-bit floating point number at the specified absolute
 * {@code index} in this buffer.  This method does not modify
 * {@code readerIndex} or {@code writerIndex} of this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if the specified {@code index} is less than {@code 0} or
 *         {@code index + 4} is greater than {@code this.capacity}
 */
public abstract float getFloat(int index);

/**
 * Gets a 64-bit floating point number at the specified absolute
 * {@code index} in this buffer.  This method does not modify
 * {@code readerIndex} or {@code writerIndex} of this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if the specified {@code index} is less than {@code 0} or
 *         {@code index + 8} is greater than {@code this.capacity}
 */
public abstract double getDouble(int index);




下面一些set*原始类型方法从索引index开始,设置原始类型,不会修改读写索引
/**
  * Sets the specified boolean at the specified absolute {@code index} in this
  * buffer.
  * This method does not modify {@code readerIndex} or {@code writerIndex} of
  * this buffer.
  *
  * @throws IndexOutOfBoundsException
  *         if the specified {@code index} is less than {@code 0} or
  *         {@code index + 1} is greater than {@code this.capacity}
  */
 public abstract ByteBuf setBoolean(int index, boolean value);
/**
 * Sets the specified 16-bit short integer at the specified absolute
 * {@code index} in this buffer.  The 16 high-order bits of the specified
 * value are ignored.
 * This method does not modify {@code readerIndex} or {@code writerIndex} of
 * this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if the specified {@code index} is less than {@code 0} or
 *         {@code index + 2} is greater than {@code this.capacity}
 */
public abstract ByteBuf setShort(int index, int value);

/**
 * Sets the specified 16-bit short integer at the specified absolute
 * {@code index} in this buffer with the Little Endian Byte Order.
 * The 16 high-order bits of the specified value are ignored.
 * This method does not modify {@code readerIndex} or {@code writerIndex} of
 * this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if the specified {@code index} is less than {@code 0} or
 *         {@code index + 2} is greater than {@code this.capacity}
 */
public abstract ByteBuf setShortLE(int index, int value);

/**
 * Sets the specified 24-bit medium integer at the specified absolute
 * {@code index} in this buffer.  Please note that the most significant
 * byte is ignored in the specified value.
 * This method does not modify {@code readerIndex} or {@code writerIndex} of
 * this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if the specified {@code index} is less than {@code 0} or
 *         {@code index + 3} is greater than {@code this.capacity}
 */
public abstract ByteBuf setMedium(int index, int value);

/**
 * Sets the specified 24-bit medium integer at the specified absolute
 * {@code index} in this buffer in the Little Endian Byte Order.
 * Please note that the most significant byte is ignored in the
 * specified value.
 * This method does not modify {@code readerIndex} or {@code writerIndex} of
 * this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if the specified {@code index} is less than {@code 0} or
 *         {@code index + 3} is greater than {@code this.capacity}
 */
public abstract ByteBuf setMediumLE(int index, int value);

/**
 * Sets the specified 32-bit integer at the specified absolute
 * {@code index} in this buffer.
 * This method does not modify {@code readerIndex} or {@code writerIndex} of
 * this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if the specified {@code index} is less than {@code 0} or
 *         {@code index + 4} is greater than {@code this.capacity}
 */
public abstract ByteBuf setInt(int index, int value);

/**
 * Sets the specified 32-bit integer at the specified absolute
 * {@code index} in this buffer with Little Endian byte order
 * .
 * This method does not modify {@code readerIndex} or {@code writerIndex} of
 * this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if the specified {@code index} is less than {@code 0} or
 *         {@code index + 4} is greater than {@code this.capacity}
 */
public abstract ByteBuf setIntLE(int index, int value);

/**
 * Sets the specified 64-bit long integer at the specified absolute
 * {@code index} in this buffer.
 * This method does not modify {@code readerIndex} or {@code writerIndex} of
 * this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if the specified {@code index} is less than {@code 0} or
 *         {@code index + 8} is greater than {@code this.capacity}
 */
public abstract ByteBuf setLong(int index, long value);

/**
 * Sets the specified 64-bit long integer at the specified absolute
 * {@code index} in this buffer in Little Endian Byte Order.
 * This method does not modify {@code readerIndex} or {@code writerIndex} of
 * this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if the specified {@code index} is less than {@code 0} or
 *         {@code index + 8} is greater than {@code this.capacity}
 */
public abstract ByteBuf setLongLE(int index, long value);

/**
 * Sets the specified 2-byte UTF-16 character at the specified absolute
 * {@code index} in this buffer.
 * The 16 high-order bits of the specified value are ignored.
 * This method does not modify {@code readerIndex} or {@code writerIndex} of
 * this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if the specified {@code index} is less than {@code 0} or
 *         {@code index + 2} is greater than {@code this.capacity}
 */
public abstract ByteBuf setChar(int index, int value);

/**
 * Sets the specified 32-bit floating-point number at the specified
 * absolute {@code index} in this buffer.
 * This method does not modify {@code readerIndex} or {@code writerIndex} of
 * this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if the specified {@code index} is less than {@code 0} or
 *         {@code index + 4} is greater than {@code this.capacity}
 */
public abstract ByteBuf setFloat(int index, float value);

/**
 * Sets the specified 64-bit floating-point number at the specified
 * absolute {@code index} in this buffer.
 * This method does not modify {@code readerIndex} or {@code writerIndex} of
 * this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if the specified {@code index} is less than {@code 0} or
 *         {@code index + 8} is greater than {@code this.capacity}
 */
public abstract ByteBuf setDouble(int index, double value);


以下一些read*原始类型方法,会修改读索引
/**
 * Gets a boolean at the current {@code readerIndex} and increases
 * the {@code readerIndex} by {@code 1} in this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if {@code this.readableBytes} is less than {@code 1}
 */
public abstract boolean readBoolean();
/**
 * Gets an unsigned byte at the current {@code readerIndex} and increases
 * the {@code readerIndex} by {@code 1} in this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if {@code this.readableBytes} is less than {@code 1}
 */
public abstract short readUnsignedByte();

/**
 * Gets a 16-bit short integer at the current {@code readerIndex}
 * and increases the {@code readerIndex} by {@code 2} in this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if {@code this.readableBytes} is less than {@code 2}
 */
public abstract short readShort();

/**
 * Gets a 16-bit short integer at the current {@code readerIndex}
 * in the Little Endian Byte Order and increases the {@code readerIndex}
 * by {@code 2} in this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if {@code this.readableBytes} is less than {@code 2}
 */
public abstract short readShortLE();

/**
 * Gets an unsigned 16-bit short integer at the current {@code readerIndex}
 * and increases the {@code readerIndex} by {@code 2} in this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if {@code this.readableBytes} is less than {@code 2}
 */
public abstract int   readUnsignedShort();

/**
 * Gets an unsigned 16-bit short integer at the current {@code readerIndex}
 * in the Little Endian Byte Order and increases the {@code readerIndex}
 * by {@code 2} in this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if {@code this.readableBytes} is less than {@code 2}
 */
public abstract int   readUnsignedShortLE();

/**
 * Gets a 24-bit medium integer at the current {@code readerIndex}
 * and increases the {@code readerIndex} by {@code 3} in this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if {@code this.readableBytes} is less than {@code 3}
 */
public abstract int   readMedium();

/**
 * Gets a 24-bit medium integer at the current {@code readerIndex}
 * in the Little Endian Byte Order and increases the
 * {@code readerIndex} by {@code 3} in this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if {@code this.readableBytes} is less than {@code 3}
 */
public abstract int   readMediumLE();

/**
 * Gets an unsigned 24-bit medium integer at the current {@code readerIndex}
 * and increases the {@code readerIndex} by {@code 3} in this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if {@code this.readableBytes} is less than {@code 3}
 */
public abstract int   readUnsignedMedium();

/**
 * Gets an unsigned 24-bit medium integer at the current {@code readerIndex}
 * in the Little Endian Byte Order and increases the {@code readerIndex}
 * by {@code 3} in this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if {@code this.readableBytes} is less than {@code 3}
 */
public abstract int   readUnsignedMediumLE();

/**
 * Gets a 32-bit integer at the current {@code readerIndex}
 * and increases the {@code readerIndex} by {@code 4} in this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if {@code this.readableBytes} is less than {@code 4}
 */
public abstract int   readInt();

/**
 * Gets a 32-bit integer at the current {@code readerIndex}
 * in the Little Endian Byte Order and increases the {@code readerIndex}
 * by {@code 4} in this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if {@code this.readableBytes} is less than {@code 4}
 */
public abstract int   readIntLE();

/**
 * Gets an unsigned 32-bit integer at the current {@code readerIndex}
 * and increases the {@code readerIndex} by {@code 4} in this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if {@code this.readableBytes} is less than {@code 4}
 */
public abstract long  readUnsignedInt();

/**
 * Gets an unsigned 32-bit integer at the current {@code readerIndex}
 * in the Little Endian Byte Order and increases the {@code readerIndex}
 * by {@code 4} in this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if {@code this.readableBytes} is less than {@code 4}
 */
public abstract long  readUnsignedIntLE();

/**
 * Gets a 64-bit integer at the current {@code readerIndex}
 * and increases the {@code readerIndex} by {@code 8} in this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if {@code this.readableBytes} is less than {@code 8}
 */
public abstract long  readLong();

/**
 * Gets a 64-bit integer at the current {@code readerIndex}
 * in the Little Endian Byte Order and increases the {@code readerIndex}
 * by {@code 8} in this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if {@code this.readableBytes} is less than {@code 8}
 */
public abstract long  readLongLE();

/**
 * Gets a 2-byte UTF-16 character at the current {@code readerIndex}
 * and increases the {@code readerIndex} by {@code 2} in this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if {@code this.readableBytes} is less than {@code 2}
 */
public abstract char  readChar();

/**
 * Gets a 32-bit floating point number at the current {@code readerIndex}
 * and increases the {@code readerIndex} by {@code 4} in this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if {@code this.readableBytes} is less than {@code 4}
 */
public abstract float readFloat();

/**
 * Gets a 64-bit floating point number at the current {@code readerIndex}
 * and increases the {@code readerIndex} by {@code 8} in this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if {@code this.readableBytes} is less than {@code 8}
 */
public abstract double readDouble();


下面是一些write*原始类型的方法,会增加写索引

/**
 * Sets the specified 16-bit short integer at the current
 * {@code writerIndex} and increases the {@code writerIndex} by {@code 2}
 * in this buffer.  The 16 high-order bits of the specified value are ignored.
 *
 * @throws IndexOutOfBoundsException
 *         if {@code this.writableBytes} is less than {@code 2}
 */
public abstract ByteBuf writeShort(int value);

/**
 * Sets the specified 16-bit short integer in the Little Endian Byte
 * Order at the current {@code writerIndex} and increases the
 * {@code writerIndex} by {@code 2} in this buffer.
 * The 16 high-order bits of the specified value are ignored.
 *
 * @throws IndexOutOfBoundsException
 *         if {@code this.writableBytes} is less than {@code 2}
 */
public abstract ByteBuf writeShortLE(int value);

/**
 * Sets the specified 24-bit medium integer at the current
 * {@code writerIndex} and increases the {@code writerIndex} by {@code 3}
 * in this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if {@code this.writableBytes} is less than {@code 3}
 */
public abstract ByteBuf writeMedium(int value);

/**
 * Sets the specified 24-bit medium integer at the current
 * {@code writerIndex} in the Little Endian Byte Order and
 * increases the {@code writerIndex} by {@code 3} in this
 * buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if {@code this.writableBytes} is less than {@code 3}
 */
public abstract ByteBuf writeMediumLE(int value);

/**
 * Sets the specified 32-bit integer at the current {@code writerIndex}
 * and increases the {@code writerIndex} by {@code 4} in this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if {@code this.writableBytes} is less than {@code 4}
 */
public abstract ByteBuf writeInt(int value);

/**
 * Sets the specified 32-bit integer at the current {@code writerIndex}
 * in the Little Endian Byte Order and increases the {@code writerIndex}
 * by {@code 4} in this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if {@code this.writableBytes} is less than {@code 4}
 */
public abstract ByteBuf writeIntLE(int value);

/**
 * Sets the specified 64-bit long integer at the current
 * {@code writerIndex} and increases the {@code writerIndex} by {@code 8}
 * in this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if {@code this.writableBytes} is less than {@code 8}
 */
public abstract ByteBuf writeLong(long value);

/**
 * Sets the specified 64-bit long integer at the current
 * {@code writerIndex} in the Little Endian Byte Order and
 * increases the {@code writerIndex} by {@code 8}
 * in this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if {@code this.writableBytes} is less than {@code 8}
 */
public abstract ByteBuf writeLongLE(long value);

/**
 * Sets the specified 2-byte UTF-16 character at the current
 * {@code writerIndex} and increases the {@code writerIndex} by {@code 2}
 * in this buffer.  The 16 high-order bits of the specified value are ignored.
 *
 * @throws IndexOutOfBoundsException
 *         if {@code this.writableBytes} is less than {@code 2}
 */
public abstract ByteBuf writeChar(int value);

/**
 * Sets the specified 32-bit floating point number at the current
 * {@code writerIndex} and increases the {@code writerIndex} by {@code 4}
 * in this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if {@code this.writableBytes} is less than {@code 4}
 */
public abstract ByteBuf writeFloat(float value);

/**
 * Sets the specified 64-bit floating point number at the current
 * {@code writerIndex} and increases the {@code writerIndex} by {@code 8}
 * in this buffer.
 *
 * @throws IndexOutOfBoundsException
 *         if {@code this.writableBytes} is less than {@code 8}
 */
public abstract ByteBuf writeDouble(double value);


下面是一些字节搜索定位方法:
/**
  * Locates the first occurrence of the specified {@code value} in this
  * buffer.  The search takes place from the specified {@code fromIndex}
  * (inclusive)  to the specified {@code toIndex} (exclusive).
  查找在当buf的fromIndex(inclusive)和toIndex(exclusive),之间是否存在指定的字节,
  找到返回对应的索引,否则返回-1
  * <p>
  * If {@code fromIndex} is greater than {@code toIndex}, the search is
  * performed in a reversed order.
  如果fromIndex大于toIndex,则反向执行搜索
  * <p>
  * This method does not modify {@code readerIndex} or {@code writerIndex} of
  * this buffer.
  此方法不会修改读写索引
  *
  * @return the absolute index of the first occurrence if found.
  *         {@code -1} otherwise.
  */
 public abstract int indexOf(int fromIndex, int toIndex, byte value);

 /**
  * Locates the first occurrence of the specified {@code value} in this
  * buffer.  The search takes place from the current {@code readerIndex}
  * (inclusive) to the current {@code writerIndex} (exclusive).
  * <p>
  从当前buf的读索引开始,到写索引之间,搜索是否存在指定字节,存在则返回第一次发生的索引,
  否则返回-1
  * This method does not modify {@code readerIndex} or {@code writerIndex} of
  * this buffer.
  此方法不会修改读写索引
  *
  * @return the number of bytes between the current {@code readerIndex}
  *         and the first occurrence if found. {@code -1} otherwise.
  */
 public abstract int bytesBefore(byte value);

 /**
  * Locates the first occurrence of the specified {@code value} in this
  * buffer.  The search starts from the current {@code readerIndex}
  * (inclusive) and lasts for the specified {@code length}.
  与上面方法不同的是,不是到写索引,而是指定了搜索返回即[readerIndex,readerIndex+length)
  * <p>
  * This method does not modify {@code readerIndex} or {@code writerIndex} of
  * this buffer.
  *此方法不会修改读写索引
  * @return the number of bytes between the current {@code readerIndex}
  *         and the first occurrence if found. {@code -1} otherwise.
  *
  * @throws IndexOutOfBoundsException
  *         if {@code length} is greater than {@code this.readableBytes}
  */
 public abstract int bytesBefore(int length, byte value);

 /**
  * Locates the first occurrence of the specified {@code value} in this
  * buffer.  The search starts from the specified {@code index} (inclusive)
  * and lasts for the specified {@code length}.
  与上面方法不同的是,从指定的索引开始搜索
  * <p>
  * This method does not modify {@code readerIndex} or {@code writerIndex} of
  * this buffer.
  *此方法不会修改读写索引
  * @return the number of bytes between the specified {@code index}
  *         and the first occurrence if found. {@code -1} otherwise.
  *
  * @throws IndexOutOfBoundsException
  *         if {@code index + length} is greater than {@code this.capacity}
  */
 public abstract int bytesBefore(int index, int length, byte value);

 再来遍历buf,处理字节:
 /**
   * Iterates over the readable bytes of this buffer with the specified {@code processor} in ascending order.
   * 遍历buf,以升序ByteProcessor#process处理字节
   * @return {@code -1} if the processor iterated to or beyond the end of the readable bytes.
   *         The last-visited index If the {@link ByteProcessor#process(byte)} returned {@code false}.
   如果迭代器超过可读索引位置,则返回-1,否则返回上次ByteProcessor#process(byte)方法,返回false的索引位置
   */
  public abstract int forEachByte(ByteProcessor processor);

  /**
   * Iterates over the specified area of this buffer with the specified {@code processor} in ascending order.
   * (i.e. {@code index}, {@code (index + 1)},  .. {@code (index + length - 1)})
   *与上面的不同的多了开始索引,和范围控制length
   * @return {@code -1} if the processor iterated to or beyond the end of the specified area.
   *         The last-visited index If the {@link ByteProcessor#process(byte)} returned {@code false}.
   */
  public abstract int forEachByte(int index, int length, ByteProcessor processor);

  /**
   * Iterates over the readable bytes of this buffer with the specified {@code processor} in descending order.
   *降序方式ByteProcessor#process处理字节
   * @return {@code -1} if the processor iterated to or beyond the beginning of the readable bytes.
   *         The last-visited index If the {@link ByteProcessor#process(byte)} returned {@code false}.
   */
  public abstract int forEachByteDesc(ByteProcessor processor);

  /**
   * Iterates over the specified area of this buffer with the specified {@code processor} in descending order.
   * (i.e. {@code (index + length - 1)}, {@code (index + length - 2)}, ... {@code index})
   *与上面的不同的多了开始索引,和范围控制length
   *
   * @return {@code -1} if the processor iterated to or beyond the beginning of the specified area.
   *         The last-visited index If the {@link ByteProcessor#process(byte)} returned {@code false}.
   */
  public abstract int forEachByteDesc(int index, int length, ByteProcessor processor);



  //ByteProcessor
 package io.netty.util;

/**
 * Provides a mechanism to iterate over a collection of bytes.
 */
public interface ByteProcessor {
    /**
     * A {@link ByteProcessor} which finds the first appearance of a specific byte.
     */
    class IndexOfProcessor implements ByteProcessor {
        private final byte byteToFind;

        public IndexOfProcessor(byte byteToFind) {
            this.byteToFind = byteToFind;
        }

        @Override
        public boolean process(byte value) {
            return value != byteToFind;
        }
    }

    /**
     * A {@link ByteProcessor} which finds the first appearance which is not of a specific byte.
     */
    class IndexNotOfProcessor implements ByteProcessor {
        private final byte byteToNotFind;

        public IndexNotOfProcessor(byte byteToNotFind) {
            this.byteToNotFind = byteToNotFind;
        }

        @Override
        public boolean process(byte value) {
            return value == byteToNotFind;
        }
    }

    /**
     * Aborts on a {@code NUL (0x00)}.
     */
    ByteProcessor FIND_NUL = new IndexOfProcessor((byte) 0);

    /**
     * Aborts on a non-{@code NUL (0x00)}.
     */
    ByteProcessor FIND_NON_NUL = new IndexNotOfProcessor((byte) 0);

    /**
     * Aborts on a {@code CR ('\r')}.
     */
    ByteProcessor FIND_CR = new IndexOfProcessor((byte) '\r');

    /**
     * Aborts on a non-{@code CR ('\r')}.
     */
    ByteProcessor FIND_NON_CR = new IndexNotOfProcessor((byte) '\r');

    /**
     * Aborts on a {@code LF ('\n')}.
     */
    ByteProcessor FIND_LF = new IndexOfProcessor((byte) '\n');

    /**
     * Aborts on a non-{@code LF ('\n')}.
     */
    ByteProcessor FIND_NON_LF = new IndexNotOfProcessor((byte) '\n');

    /**
     * Aborts on a {@code CR (';')}.
     */
    ByteProcessor FIND_SEMI_COLON = new IndexOfProcessor((byte) ';');

    /**
     * Aborts on a {@code CR ('\r')} or a {@code LF ('\n')}.
     */
    ByteProcessor FIND_CRLF = new ByteProcessor() {
        @Override
        public boolean process(byte value) {
            return value != '\r' && value != '\n';
        }
    };

    /**
     * Aborts on a byte which is neither a {@code CR ('\r')} nor a {@code LF ('\n')}.
     */
    ByteProcessor FIND_NON_CRLF = new ByteProcessor() {
        @Override
        public boolean process(byte value) {
            return value == '\r' || value == '\n';
        }
    };

    /**
     * Aborts on a linear whitespace (a ({@code ' '} or a {@code '\t'}).
     */
    ByteProcessor FIND_LINEAR_WHITESPACE = new ByteProcessor() {
        @Override
        public boolean process(byte value) {
            return value != ' ' && value != '\t';
        }
    };

    /**
     * Aborts on a byte which is not a linear whitespace (neither {@code ' '} nor {@code '\t'}).
     */
    ByteProcessor FIND_NON_LINEAR_WHITESPACE = new ByteProcessor() {
        @Override
        public boolean process(byte value) {
            return value == ' ' || value == '\t';
        }
    };

    /**
     * @return {@code true} if the processor wants to continue the loop and handle the next byte in the buffer.
     *         {@code false} if the processor wants to stop handling bytes and abort the loop.
     */
    boolean process(byte value) throws Exception;
}

0
0
分享到:
评论

相关推荐

    java实现基于netty 的udp字节数据接收服务

    在Java编程环境中,Netty是一个高性能、异步事件驱动的网络应用程序框架,常用于构建可伸缩、高并发的服务器。本示例关注的是如何利用Netty实现一个基于UDP(User Datagram Protocol)的数据接收服务,这在需要进行...

    基于netty4 的udp字节数据接收服务

    Netty 是一个高性能、异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。在本文中,我们将深入探讨如何利用 Netty 4 构建基于 UDP(用户数据报协议)的数据接收服务,以及如何实现...

    Netty进制转换乱码问题

    1. **字符编码与字节流**:在计算机系统中,字符和字节的对应关系是由字符编码(如ASCII、UTF-8、GBK等)定义的。不同的编码方式会导致相同的字符表示为不同的字节序列,如果在发送端和接收端使用了不同的编码方式,...

    netty 在java中的字节码转换

    netty通信时经常和底层数据交互,C语言和java的数据类型和范围不同,通信时需要转化或兼容,附件为字节码、进制常用的转换类。

    Netty-入门Netty编码

    在 Netty 中,数据传输通常涉及 ByteBuf,这是 Netty 提供的高效字节缓冲区。ByteBuf 可以动态调整容量,支持读写索引,使得在网络编程中更加灵活和高效。 此外,Netty 还提供了多种编解码器,如 ...

    netty服务器解析16进制数据

    分析这个代码,我们可以看到Netty如何创建服务器、设置管道、以及如何定义和使用自定义的解码器和编码器来处理16进制数据。 通过上述步骤,Netty服务器可以轻松地解析16进制数据,从而支持各种网络协议,无论它们是...

    java netty学习资料

    Netty提供了一种灵活的方式来定义自定义的编解码器,允许我们创建复杂的消息协议。这些编解码器可以将网络数据流转换为应用程序可理解的对象,反之亦然。例如,你可以创建一个特定的协议头解析器来识别协议头,并将...

    整合netty实时通讯

    - 使用 Netty 创建 WebSocket 服务器,首先需要定义一个 ChannelInitializer,配置处理 WebSocket 数据的 ChannelHandler。例如,WebSocketFrameDecoder 和 WebSocketFrameEncoder 用于解码和编码 WebSocket 帧。 ...

    c++客户端和java(Netty)服务器端tcp通讯

    首先,TCP(传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议,它确保了数据包的顺序和完整性。在C++中,我们可以使用标准库中的`&lt;sys/socket.h&gt;`和`&lt;netinet/in.h&gt;`来创建和管理socket,进行...

    基于netty编写的socket服务端

    在基于Netty编写的socket服务端中,首先需要定义一个`ChannelHandler`,这个处理器负责处理接收到的网络事件,如连接建立、数据读取、连接关闭等。`ChannelHandlerContext`则是`ChannelHandler`和`ChannelPipeline`...

    netty所需要得jar包

    - ByteBuf是Netty的缓冲区,提供了高效的字节操作和内存管理。 7. **Netty-all-4.1.25.Final.jar**: - 这个jar包是Netty的全功能集,包含了Netty所有模块的类和依赖,适用于快速搭建项目,避免单独导入多个jar包...

    netty-netty-4.1.69.Final.tar.gz

    2. **高效性**:Netty通过减少对象创建和内存复制来优化性能,例如,它的ByteBuf类提供了高效的字节缓冲区管理。 3. **灵活性**:Netty支持多种网络协议,如TCP、UDP、HTTP、WebSocket、FTP等,以及自定义协议。它...

    netty4.0源码,netty例子,netty api文档

    3. **ByteBuf**:Netty提供的ByteBuf作为字节缓冲区,比Java的ByteBuffer更加灵活和高效。它支持读写指针独立移动,避免了不必要的内存复制。 4. **Pipeline**:Netty的ChannelHandler链是通过Pipeline实现的。...

    Netty实战.epub_netty实战epub_netty实战epub_netty_

    《Netty实战》这本书是针对Java网络编程框架Netty的一本深入实践教程,旨在帮助读者掌握Netty的核心特性和实际应用。Netty是一款高性能、异步事件驱动的网络应用程序框架,广泛应用于各种分布式系统、微服务架构以及...

    netty官网学习手册中文版

    - **ByteBuf**:Netty自定义的高效字节缓冲区,比Java的ByteBuffer更易用且性能更好。 - **ChannelHandler**:处理器接口,用于实现I/O事件的处理逻辑。 - **Bootstrap**:启动器,用于配置并启动服务器或客户端...

    Netty基础,用于学习Netty,参考黑马程序员的netty教程

    Netty基础,用于学习Netty,参考黑马程序员的netty教程

    netty简单实例

    通常,我们还需要添加预定义的处理器,如 ByteToMessageDecoder 和 MessageToByteEncoder,以处理基础的字节流转换。 3. **启动 ServerBootstrap**:在服务器端,使用 ServerBootstrap 绑定一个端口,监听连接请求...

    跟闪电侠学Netty:Netty即时聊天实战与底层原理-book-netty.zip

    《跟闪电侠学Netty:Netty即时聊天实战与底层原理》是一本深入浅出的Netty技术指南,旨在帮助读者掌握Netty框架,并利用它实现即时聊天应用,同时理解其底层工作原理。Netty是Java领域的一款高性能、异步事件驱动的...

    Netty实战 电子版.pdf_java_netty_服务器_

    《Netty实战》是针对Java开发者的一本技术指南,它深入介绍了如何利用Netty这个高性能、异步事件驱动的网络应用程序框架来构建高效且可扩展的网络应用。Netty不仅简化了网络编程的复杂性,还提供了丰富的特性和组件...

    深入浅出Netty_netty_

    还会介绍如何定义自定义的编码解码器来处理特定的协议格式。对于协议解析,Netty提供了零拷贝机制,能有效减少内存复制,提高效率。 除此之外,Netty还提供了强大的心跳检测机制,可以防止因网络延迟或故障导致的...

Global site tag (gtag.js) - Google Analytics