• NIO教程笔记


    NIO操作文件部分详解

    NIO——New IO,也可以理解为非阻塞IO(Non Blocking IO)。可以替代旧IO,更高效的支持读写(文件读写,网络读写)。但文件操作都是阻塞的。学习NIO首先要了解缓冲区(Buffer),通道(Channel)。

    一.缓冲区(七种类型)——专门用于存取各种基本类型数据(除Boolean)的地方。(如果已经了解,请点击这里)

    1.缓冲区的类型有ByteBuffer,ShortBuffer,IntBuffer,LongBuffer,DoubleBuffer,FloatBuffer,CharBuffer用于存储不同类型的数据。通过xxBuffer.allocate()分配空间

    2.缓冲区的几个重要属性:

      (1).private int limit——缓冲区中数据的界限,即limit之后的数据不会读取

      (2).private int position = 0——缓冲区中当前操作数据的位置。

      (3).private int capacity——缓冲区的最大容量,不会改变(就像数组初始化大小后不会改变一个道理)。

      (4).private int mark = -1——可标记position的位置,通过reset()回到mark位置。

    3.xxBuffer的几个重要方法:

      (1).put();向缓冲区写数据。

      (2).get();从缓冲区读数据。

      (3).rewind();重复读取数据。

      (4).clear();清除数据(非抹除数据,只是重置limit,position,capacity的值,原数据依然存在)。

    3.举例:
      ByteBuffer bf = ByteBuffer.allocate(10);
      此时limit,position ,capacity的数值如图所示。

      

        bf.put("abcde".getBytes());后各个数值如下。(写入数据)

        

        bf.flip();后各个数值如下(flip函数为切换模式,从写模式切换到读模式)。

        

    二、通道(Channel)(如果已经了解,请点击这里)

    通道负责双向传输缓冲区的数据(传统的IO是单向的,reader读,writer写),通过缓冲区flip()来切换读、写模式。在Java NIO中,负责缓冲区中数据传输,Channel本身不存储数据,因此需要配合缓冲区进行传输。

    能够获得channel的方式:

    本地IO:FileInputStream FileOutputStream RandomAccessFile

    网络IO: Socket ServerSocket DatagramSocket

    三、代码展示

    File file = new File();
    Charset utfEncode = Charset.forName("UTF-8");
    CharsetDecoder utfDecoder = utfEncode.newDecoder();

    ByteBuffer buff = ByteBuffer.allocate((int) file.length());
    CharBuffer charbuff = CharBuffer.allocate((int) file.length());
    FileInputStream fis = null;
    FileChannel channel = null;
    StringBuilder context = new StringBuilder();

    try {
    //创建流
    fis = new FileInputStream(file);
    //获取channel
    channel = fis.getChannel();

    int count = channel.read(buff);

    while(count > -1) {
    buff.flip();
    count = channel.read(buff);
    }

    while(buff.hasRemaining()) {
    utfDecoder.decode(buff, charbuff, false);
    charbuff.flip();
    context.append(charbuff);
    }
    System.out.println(context);
    } catch (IOException e) {
    e.printStackTrace();
    }finally {
    if(fis != null) {
    try {
    buff.clear();
    buff = null;
    fis.close();
    channel.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }

  • 相关阅读:
    大数据量分表时 两个表查询比较快的方式
    开启SQL Server执行占用时间显示和逻辑读取次数显示
    【转】SQL Server海量数据库的索引、查询优化及分页算法
    Exchange无法发送邮件 未找到匹配的连接器来路由外部收件人解决办法
    HTML介绍&常用的标签
    关于HTML文件、JS文件、CSS文件
    python命名空间和作用域
    pymysql
    存储过程、视图、触发器、函数
    多表查询
  • 原文地址:https://www.cnblogs.com/chxwkx/p/10385780.html
Copyright © 2020-2023  润新知