java IO缓冲器
(2012-04-22 12:41:21)
标签:
杂谈
分类:
IT
1、用缓冲器操纵数据
这个图解阐明了 nio 类之间的关系,便于我们理解怎么移动和转换数据。例如,如果我们想
把一个字节数组写到文件中去,那么我们就应该使用ByteBuffer.wrap( )方法把字节数组
包装起来,然后用getChannel( )方法在FileOutputStream 上打开一个通道,接着将来
自于ByteBuffer 的数据写到FileChannel 中。
注意:ByteBuffer 是将数据移进移出通道的唯一方式,并且我们只能创建一个独立的基本
类型缓冲器,或者使用“as”方法从ByteBuffer 中获得。也就是说,我们不能把基本类型的
缓冲器转换成ByteBuffer。然而,由于我们可以经由视图缓冲器将基本类型数据移进移出
ByteBuffer,所以这也就不是什么真正意义上的限制了。
2、缓冲器的细节
缓冲器由数据和可以高效地访问及操纵这些数据的四个索引组成,这四个索引是:mark,
position,limit 和capacity。下面是用于设置和复位索引以及查询数据的方法。
capacity( ) 返回缓冲区容量
clear( ) 清空缓冲区,将position 设置为0,limit 设置为容量。
我们可以调用此方法覆写缓冲区。
flip( ) 将 limit 设置为position , position 设置为 0。此方
法用于准备从缓冲区读取已经写入的数据。
limit( ) 返回 limit 值
limit(int lim) 设置 limit 值.
mark( ) 将 mark 设置为position.
position( ) 返回 position 值.
position(int pos) 设置 position 值。
remaining( ) 返回 (limit - position).
hasRemaining( ) 若有介于 position 和 limit.之间的元素,则返回
trueReturns true。
下面的示例用到一个很简单的算法(交换相邻字符)对CharBuffer 中的字符进行编码和译
码。
//: c12:UsingBuffers.java
import java.nio.*;
import com.bruceeckel.simpletest.*;
public class UsingBuffers {
private static Test monitor = new Test();
private static void symmetricScramble(CharBuffer buffer){
while(buffer.hasRemaining()) {
buffer.mark();
char c1 = buffer.get();
char c2 = buffer.get();
buffer.reset();
buffer.put(c2).put(c1);
}
}
public static void main(String[] args) {
char[] data = "UsingBuffers".toCharArray();
ByteBuffer bb = ByteBuffer.allocate(data.length * 2);
CharBuffer cb = bb.asCharBuffer();
cb.put(data);
System.out.println(cb.rewind());
symmetricScramble(cb);
System.out.println(cb.rewind());
symmetricScramble(cb);
System.out.println(cb.rewind());
monitor.expect(new String[] {
"UsingBuffers",
"sUniBgfuefsr",
"UsingBuffers"
});
}
} ///:~
尽管你可以通过对某个char 数组调用wrap( )方法来直接产生一个CharBuffer,但是在
本例中取而代之的是分配一个底层的ByteBuffer,产生的CharBuffer 只是ByteBuffer
上的一个视图而已。这里要强调我们总是以操纵使用ByteBuffer 为目标这个事实,因为它
可以和通道进行交互。
下面是 Put()之后,缓冲器的样子:
position 指针指向缓冲器中的第一个元素,capacity 和limit 则指向最后一个元素。
在程序的 symmetricScramble( )方法中,迭代执行while 循环直到position 等于limit。
一旦调用缓冲器上的相对的get()或put()功能,position 指针就会随之相应改变。我
们也可以调用绝对的、包含一个参数的get()和put()方法,参数指待get()或put
()的发生位置。不过,这些方法不会改变缓冲器的position 指针。
当操纵到 while 循环时,使用 mark()调用来设置mark 的值。此时,缓冲器状态如下:
两个相对的get()调用把前两个字符保存到变量c1 和c2 中,调用完这两个方法后,缓
冲器如下:
为了实现交换,我们要在position=0 时写入c2,position=1 时写入c1。我们也可以使
用绝对输入方法来实现,或者使用reset()把position 的值设为mark 的值:
这两个 put()方法先写c2,接着写c1:
在下一次循环迭代期间,将 mark 设置成position 的当前值:
这个过程将会持续到遍历完整个缓冲器。在 while 循环的最后,position 指向缓冲器的末
尾。所以如果想要打印缓冲器,只能打印出position 和limit 之间的字符。因此,如果想
显示缓冲器的全部内容,我们必须使用rewind()把position 设置到缓冲器的开始位置。
下面是调用rewind()之后缓冲器的状态(mark 的值则变得不明确):
当再次调用symmetricScramble( )功能时,会对CharBuffer 进行同样的处理,并将其
恢复到初始状态。
分享:
喜欢
0
赠金笔
加载中,请稍候......
评论加载中,请稍候...
发评论
登录名: 密码: 找回密码 注册记住登录状态
昵 称:
评论并转载此博文
发评论
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。