NIO

建议别听我bb,直接跳转这个页面:
NIO教程

NIO是面向缓存的非阻塞流,而且功能很强大。

Channel

  • Channel基本上是所有NIO的开始
  • 可以异步读写数据
  • Channel中的数据总是要先读到一个Buffer,或者总是要从一个Buffer中写入
  • 有以下主要实现:
    FileChannel:文件
    DatagramChannel:UDP
    SocketChannel:TCP
    ServerSocketChannel:监听新进来的TCP连接

Buffer

Java NIO中的Buffer用于和NIO通道进行交互。如你所知,数据是从通道读入缓冲区,从缓冲区写入到通道中的。
缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存。这块内存被包装成NIO Buffer对象,并提供了一组方法,用来方便的访问该块内存。
可以理解为,Buffer就是缓存

使用Buffer读写数据一般遵循以下四个步骤:
1. 写入数据到Buffer
2. 调用flip()方法
3. 从Buffer中读取数据
4. 调用clear()方法或者compact()方法

当向buffer写入数据时,buffer会记录下写了多少数据。一旦要读取数据,需要通过flip()方法将Buffer从写模式切换到读模式。在读模式下,可以读取之前写入到buffer的所有数据。

一旦读完了所有的数据,就需要清空缓冲区,让它可以再次被写入。有两种方式能清空缓冲区:调用clear()或compact()方法。clear()方法会清空整个缓冲区。compact()方法只会清除已经读过的数据。任何未读的数据都被移到缓冲区的起始处,新写入的数据将放到缓冲区未读数据的后面。

读:

RandomAccessFile aFile = new RandomAccessFile("d:/1.txt", "rw");
FileChannel fc = aFile.getChannel();
ByteBuffer buf = ByteBuffer.allocate(48);//分配48字节的Capacity

/*pos=0;limit=48*/
int bytesRead = fc.read(buf);//从Channel写到Buffer
/*pos=5;limit=48*/
while (bytesRead != -1) {
    /*
     * Buffer 中的 flip() 方法涉及到 Buffer 中的Capacity、Position、Limit三个概念。
     * Capacity(容量):在读写模式下都是固定的,就是我们分配的缓冲大小。 
     * Position(位置):类似于读写指针,表示当前读(写)到什么位置。
     * Limit(限制):在写模式下表示最多能写入多少数据,此时和Capacity相同。在读模式下表示最多能读多少数据,此时和缓存中的实际
     *          数据大小相同。 
     * 在写模式下调用 flip()方法,那么limit就设置为了position当前的值(即当前写了多少数据),position会被置为0,
     * 以表示读操作从缓存的头开始读。也就是说调用flip之后,读写指针指到缓存头部,并且设置了最多只能读出之前写入的数据长度(
     * 而不是整个缓存的容量大小)。
     */
    buf.flip();//使缓冲区为一系列新的通道读取或相对放置 操作做好准备:它将limit设置为position大小,将position设置为 0
                //将写模式切换到读模式
                //ready for read

    /*pos=0;limit=5*/
    while (buf.hasRemaining()) {//判断当前位置与限制为之间是否有元素
        System.out.println(buf.position()+":"+(char)buf.get()); 
    }
    /*pos=5;limit=5*/
    buf.clear();//使缓冲区为一系列新的通道写入或相对获取 操作做好准备:它将limit设置为Capacity,然后将position设置为 0。
                //清空缓冲区,便于下次写入
                //ready for write
                //这句必须有,否则fc.read(buf)不会返回-1,然后就无限循环
    /*pos=0;limit=48*/
    bytesRead = fc.read(buf);
}
aFile.close();

写:

RandomAccessFile aFile = new RandomAccessFile("d:/1.txt", "rw");
FileChannel fc = aFile.getChannel();
ByteBuffer head = ByteBuffer.allocate(48);
head.put("1234".getBytes());//写数据有两种方式:1.直接使用buffer的put方法。2.从Channel中写入数据
head.flip();
fc.write(head);//buffer写到channel,从position开始,一直写到limit

可以通道之间传递数据:

RandomAccessFile fromFile = new RandomAccessFile("d:/1.txt", "rw");
FileChannel fromChannel=fromFile.getChannel();
RandomAccessFile toFile = new RandomAccessFile("d:/2.txt", "rw");
FileChannel toChannel=toFile.getChannel();
//fromChannel.transferTo(0, fromChannel.size(),toChannel);
toChannel.transferFrom(fromChannel,0,fromChannel.size());
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值