NIO与Socket编程技术指南
上QQ阅读APP看书,第一时间看更新

1.5 CharBuffer类的API使用

CharBuffer类提供一个字符(char)序列缓冲区。

1.5.1 重载append(char)/append(CharSequence)/append(CharSequence, start, end)方法的使用

public CharBuffer append(char c)方法的作用:将指定字符添加到此缓冲区(可选操作)。调用此方法的形式为dst.append(c),该调用与以下调用完全相同:dst.put(c)。

public CharBuffer append(CharSequence csq)方法的作用:将指定的字符序列添加到此缓冲区(可选操作)。调用此方法的形式为dst.append(csq),该调用与以下调用完全相同:dst.put(csq.toString()),有可能没有添加整个序列,这取决于针对字符序列csq的toString规范。例如,调用字符缓冲区的toString()方法将返回一个子序列,其内容取决于缓冲区的位置和限制。

public CharBuffer append(CharSequence csq, int start, int end)方法的作用:将指定字符序列的子序列添加到此缓冲区(可选操作)。当csq不为null时,调用此方法的形式为dst. append(csq, start, end),该调用与以下调用完全相同:dst.put(csq.subSequence(start, end). toString())。

示例代码如下:

public class Test1 {
public static void main(String[] args) {
    CharBuffer charbuffer = CharBuffer.allocate(15);
    System.out.println("A " + charbuffer.position());
    charbuffer.append('a');
    System.out.println("B " + charbuffer.position());
    charbuffer.append("bcdefg");
    System.out.println("C " + charbuffer.position());
    charbuffer.append("abchijklmn", 3, 8);
    System.out.println("D " + charbuffer.position());
    char[] newArray = charbuffer.array();
    for (int i = 0; i < newArray.length; i++) {
        System.out.print(newArray[i] + " ");
    }
    System.out.println();
    System.out.println("charbuffer capacity=" + charbuffer.capacity());
}
}

程序运行结果如下:

A 0
B 1
C 7
D 12
a b c d e f g h i j k l
charbuffer capacity=15

1.5.2 读取相对于当前位置的给定索引处的字符

public final char charAt(int index)方法的作用:读取相对于当前位置的给定索引处的字符。

示例代码如下:

public class Test2 {
public static void main(String[] args) {
    CharBuffer charbuffer = CharBuffer.allocate(10);
    charbuffer.append("abcdefg");
    charbuffer.position(2);
    System.out.println(charbuffer.charAt(0));
    System.out.println(charbuffer.charAt(1));
    System.out.println(charbuffer.charAt(2));
}
}

程序运行结果如下:

c
d
e

1.5.3 put(String src)、int read(CharBuffer target)和subSequence(int start, int end)方法的使用

put(String src)方法的作用:相对批量put方法(可选操作)。此方法将给定源字符串中的所有内容传输到此缓冲区的当前位置。调用此方法的形式为dst.put(s),该调用与以下调用完全相同:dst.put(s, 0, s.length())。

int read(CharBuffer target)方法的作用:试图将当前字符缓冲区中的字符写入指定的字符缓冲区。缓冲区可照原样用作字符的存储库:所做的唯一更改是put操作的结果。不对缓冲区执行翻转或重绕操作。

subSequence(int start, int end)方法的作用:创建表示此缓冲区的指定序列、相对于当前位置的新字符缓冲区。新缓冲区将共享此缓冲区的内容,即如果此缓冲区的内容是可变的,则修改一个缓冲区将导致另一个缓冲区被修改。新缓冲区的容量将为此缓冲区的容量,其位置将为position() + start,其限制将为position() + end。当且仅当此缓冲区为直接缓冲区时,新缓冲区才是直接缓冲区。当且仅当此缓冲区为只读时,新缓冲区才是只读的。其中两个参数的解释如下。

1)start:子序列中第一个字符相对于当前位置的索引;必须为非负且不大于remaining()。

2)end:子序列中最后一个字符后面的字符相对于当前位置的索引;必须不小于start且不大于remaining()。

示例代码如下:

public class Test3 {
public static void main(String[] args) throws IOException {
    CharBuffer buffer1 = CharBuffer.allocate(8);
    buffer1.append("ab123456");
    buffer1.position(2);
    buffer1.put("cde");
    buffer1.rewind();
    for (int i = 0; i < buffer1.limit(); i++) {
        System.out.print(buffer1.get());
    }
    System.out.println();
    buffer1.position(1);
    CharBuffer buffer2 = CharBuffer.allocate(4);
    System.out.println("A buffer2 position=" + buffer2.position());
    buffer1.read(buffer2); // read()相当于position是1进行导出
    System.out.println("B buffer2 position=" + buffer2.position());
    buffer2.rewind();
    for (int i = 0; i < buffer2.limit(); i++) {
        System.out.print(buffer2.get());
    }
    System.out.println();
    buffer1.position(2);
    CharBuffer buffer3 = buffer1.subSequence(0, 2);
    System.out.println("C buffer3 position=" + buffer3.position() + " capacity=" +
        buffer3.capacity() + " limit="
            + buffer3.limit());
    for (int i = buffer3.position(); i < buffer3.limit(); i++) {
        System.out.print(buffer3.get());
    }
}
}

程序运行结果如下:

abcde456
A buffer2 position=0
B buffer2 position=4
bcde
C buffer3 position=2 capacity=8 limit=4
cd

1.5.4 static CharBuffer wrap(CharSequence csq, int start, int end)方法的使用

public static CharBuffer wrap(CharSequence csq, int start, int end)方法的作用:将字符序列包装到缓冲区中。新的只读缓冲区的内容将为给定字符序列的内容。缓冲区的容量将为csq.length(),其位置将为start,其限制将为end,其标记是未定义的。

1)参数csq代表字符序列,新的字符缓冲区将从中创建。

2)参数start代表要使用的第一个字符的索引,必须为非负且不大于csq.length()。新缓冲区的位置将被设置为此值。

3)参数end代表要使用的最后一个字符后面的字符的索引,必须不小于start且不大于csq.length()。将新缓冲区的限制设置为此值。返回值是新的字符缓冲区。

示例代码如下:

public class Test4 {
public static void main(String[] args) throws IOException {
    CharBuffer charbuffer1 = CharBuffer.wrap("abcdefg", 3, 5);
    System.out.println("capacity=" + charbuffer1.capacity() + " limit=" +
        charbuffer1.limit() + " position="
            + charbuffer1.position());
    for (int i = 0; i < charbuffer1.limit(); i++) {
        System.out.print(charbuffer1.get(i) + " ");
    }
    charbuffer1.append("我是只读的,不能添加数据,会出现异常!");
}
}

程序运行结果如下:

capacity=7 limit=5 position=3
Exception in thread "main" a b c d e java.nio.ReadOnlyBufferException
    at java.nio.CharBuffer.put(CharBuffer.java:920)
    at java.nio.CharBuffer.put(CharBuffer.java:950)
    at java.nio.CharBuffer.append(CharBuffer.java:1351)
    at CharBufferAPITest.Test4.main(Test4.java:14)

1.5.5 获得字符缓冲区的长度

public final int length()方法的作用:返回此字符缓冲区的长度。当将字符缓冲区视为字符序列时,长度只是该位置(包括)和限制(不包括)之间的字符数,即长度等效于remaining()。

length()方法的内部源代码如下:

public final int length() {
    return remaining();
}

示例代码如下:

public class Test5 {
public static void main(String[] args) throws IOException {
    CharBuffer charbuffer1 = CharBuffer.wrap("abcd");
    System.out.println("position=" + charbuffer1.position() + " remaining=" +
    charbuffer1.remaining() + " length="
            + charbuffer1.length());
    System.out.println(charbuffer1.get());
    System.out.println("position=" + charbuffer1.position() + " remaining=" +
        charbuffer1.remaining() + " length="
            + charbuffer1.length());
    System.out.println(charbuffer1.get());
    System.out.println("position=" + charbuffer1.position() + " remaining=" +
        charbuffer1.remaining() + " length="
            + charbuffer1.length());
    System.out.println(charbuffer1.get());
    System.out.println("position=" + charbuffer1.position() + " remaining=" +
        charbuffer1.remaining() + " length="
            + charbuffer1.length());
    System.out.println(charbuffer1.get());
    System.out.println("position=" + charbuffer1.position() + " remaining=" +
        charbuffer1.remaining() + " length="
            + charbuffer1.length());
}
}

程序运行结果如下:

position=0 remaining=4 length=4
a
position=1 remaining=3 length=3
b
position=2 remaining=2 length=2
c
position=3 remaining=1 length=1
d
position=4 remaining=0 length=0