Java NIO

概述:

  NIO核心:Channel、Buffer、Selector(非阻塞式输入/输出)。传统的IO基于字节流和字符流进行操作,而NIO基于Channel和Buffer进行操作,数据从通道读到缓冲区或者从缓冲区写到通道中;传统IO和NIO都是用于进行输入/输出的功能,但NIO采用了内存映射文件的方式来处理输入/输出,NIO将文件或文件的一端区域映射到内存中,这样就可以像访问内存一样来访问文件;

  Channel是对传统输入/输出系统中的模拟,在NIO系统中所有数据都需要通过通道传输;Channel与InputStream、OutputStream最大的区别在于它提供了一个map方法,通过map方法可以直接将“一块数据”映射到内存中。如果传统的输入/输出是面向流的,则NIO是面向块的;

  Buffer则是一个容器,本质是一个数组,发送到Channel中的所有对象都需先放到Buffer中,而从Channel中取到的数据也需先读到Buffer中;

Buffer:

  Buffer是一个抽象类,其子类:ByteBuffer, CharBuffer, DoubleBuffer, FloatBuffer, IntBuffer, LongBuffer, ShortBuffer;

  Buffer的三个概念:

  • 容量:是它所包含的元素的数量。缓冲区的容量不能为负并且不能更改;
  • 界限:第一个不应该读取或写入的元素的索引。缓冲区的限制不能为负,并且不能大于其容量,即位于其后的数据不可读也不可写;
  • 位置:下一个要读取或写入的元素的索引。缓冲区的位置不能为负,并且不能大于其限制。对于每个非 boolean 基本类型,此类都有一个子类与之对应。

Buffer还有一个可选的标记(mark),该mark允许程序直接将position定位到mark处;

0\leqslant mark \leqslant position \leqslant limit \leqslant capacity

Buffer类定义了对缓冲区进行的操作:

  • clear():使缓冲区为一系列新的通道读取或相对放置 操作做好准备:它将限制设置为容量大小,将位置设置为 0(执行以后,该Buffer对象里的数据依然存在)。
  • flip():使缓冲区为一系列新的通道写入或相对获取 操作做好准备:它将限制设置为当前位置,然后将位置设置为 0。
  • rewind():使缓冲区为重新读取已包含的数据做好准备:它使限制保持不变,将位置设置为 0;
方法摘要
abstract  Objectarray()
          返回此缓冲区的底层实现数组(可选操作)
abstract  intarrayOffset()
          返回此缓冲区的底层实现数组中第一个缓冲区元素的偏移量(可选操作)
 intcapacity()
          返回此缓冲区的容量。
 Bufferclear()
          清除此缓冲区。
 Bufferflip()
          反转此缓冲区。
abstract  booleanhasArray()
          告知此缓冲区是否具有可访问的底层实现数组。
 booleanhasRemaining()
          告知在当前位置和限制之间是否有元素。
abstract  booleanisDirect()
          告知此缓冲区是否为直接缓冲区
abstract  booleanisReadOnly()
          告知此缓冲区是否为只读缓冲区。
 intlimit()
          返回此缓冲区的限制。
 Bufferlimit(int newLimit)
          设置此缓冲区的限制。
 Buffermark()
          在此缓冲区的位置设置标记。
 intposition()
          返回此缓冲区的位置。
 Bufferposition(int newPosition)
          设置此缓冲区的位置。
 intremaining()
          返回当前位置与限制之间的元素数。
 Bufferreset()
          将此缓冲区的位置重置为以前标记的位置。
 Bufferrewind()
          重绕此缓冲区。
public static void main(String[] args) {
        CharBuffer charBuffer=CharBuffer.allocate(8);
        System.out.println(charBuffer.capacity());
        System.out.println(charBuffer.limit());
        System.out.println(charBuffer.position());
        charBuffer.put('A');
        charBuffer.put('B');
        charBuffer.put('C');
        System.out.println(charBuffer.position());
        charBuffer.flip();
        System.out.println(charBuffer.limit());
        charBuffer.clear();
        System.out.println(charBuffer.capacity());
        System.out.println(charBuffer.limit());
        System.out.println(charBuffer.position());
        System.out.println(charBuffer.get(2));
    }

Channel:

  Channel类似于传统的流对象,但有两个区别:

  • Channel可以直接将指定文件的部分或全部直接映射成Buffer;
  • 程序不能直接访问Channel中的数据,包括读写,Channel只能与Buffer进行交互;

 

public static void main(String[] args) {
        Path path=null;
        FileChannel fileChannel=null;
        try{
            path= Paths.get("C:\\Users\\Administrator\\IdeaProjects\\FUXI\\src\\nio\\TestBuffer.java");
            fileChannel=FileChannel.open(path, StandardOpenOption.READ);
            ByteBuffer byteBuffer=ByteBuffer.allocate(1024);
            int readLine=-1;
            while ((readLine=fileChannel.read(byteBuffer))>0){
                byteBuffer.flip();
                Charset charset=Charset.forName("UTF-8");
                System.out.println(charset.decode(byteBuffer));
                byteBuffer.clear();
            }
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            try {
                fileChannel.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Dream答案

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值