NIO

NIO概述

为什么了有了IO,还需要有NIO?

* NIO在JDK1.4后引入的

* NIO是面向块(缓冲区)编程,旧IO是面向流编程

*

* IO     NIO

* 面向流          面向缓冲区

* 阻塞IO 非阻塞IO

* 无           选择器

*

* Java中针对IO的一些核心的包和接口、类

*

* java.nio 主要包含了各种与Buffer相关的类

* java.nio.channel 主要包含了与Channel和Selector相关的类和接口

* java.nio.charset 主要包含了与编码相关的类接口

* java.nio.channels.spi 主要包含了与Channel相关的服务提供者编程接口

* javan.nio.charset.spi 主要包含了与charset相关的服务提供者编程接口

*

*

* 目前需要掌握的核心就是三个包

* Buffer

* Channel

* CharSet

*

* 面向缓冲区编程:

*         数据的读写必须经过缓冲区

*  我们可以使用Buffer所对应的子类来数据从通道(Channel)流向缓冲区

*  从缓冲区写到通道叫做读取缓冲区

Buffer缓冲区

Buffer

* Buffer是一个抽象类

* 子类有

*         ByteBuffer, CharBuffer, DoubleBuffer, FloatBuffer, IntBuffer, LongBuffer, ShortBuffer

*

* 核心类

*         ByteBuffer和CharBuffer

* ByteBuffer有一个子类 MappedByteBuffer

* MappedByteBuffer类能够将文件直接映射到内存中,那么这样我们就可以像访问内存一样访问文件,非常方便

*

* 获取Buffer

*         获取ByteBuffer

*                 static ByteBuffer allocate(int capacity)

                         分配一个新的字节缓冲区。

               static ByteBuffer allocateDirect(int capacity)

                         分配新的直接字节缓冲区。

        二者获取Buffer的区别

        1.创建普通Buffer成本低,读写的效率不高

        2.因为创建直接Buffer成本高,所以我们一般用在Buffer生存周期较长的时候使用

        3.只有ByteBuffer才能够创建直接Buffer,其他的Buffer对象是不能够创建

        4.如果创建了直接Buffer但是我又想要使用其他Buffer的功能,可以将ByteBuffer转换成其他Buffer

                        asIntBuffer()

* 四个非常重要的概念

*         capacity: 缓冲区的容量,不可以为负数,一旦创建了就不能够改变

*  limit: 无效缓冲区的第一个位置索引,limit后面的数据既不可读,也不可写

*  position : 下一个可以被读取或者写入的缓冲区位置索引

*  mark: 标记索引,该索引能够用于下次读取或者写入,它只能够在0-position之间

*  

*  四个系数的关系:

*          0 < mark < postion < limit < capacity

*  

*  五个方法

*          flip(): 将写模式切换为读模式, 将limit的值改为postion的值,同时将postion归0

*                          特点: 就是为下一次数据的读取做好准备

*          clear(): 将读模式切换为写模式,将limit改为capacity的值,同时将postion归0

*                          特点: 就是为下一次数据的写入做好准备

*          put(): 相对读取,向Buffer中存储数据

*          get(): 相对读取,从Buffer中获取数据

*          hasRemaining(): 判断当前位置和limit之间是否还有元素可处理

*

* 绝对读取: get(index) 不会影响position的位置

* 相对读取: put() get() 会影响,每次读取一次,指针后移

*/

public class NIODemo02 {

       public static void main(String[] args) {

//                ByteBuffer buffer = ByteBuffer.allocate(5);

//                ByteBuffer buffer2 = ByteBuffer.allocateDirect(10);

               CharBuffer buffer = CharBuffer.allocate(8);

               // Buffer已经准备好了向Buffer中写数据    写模式

               System.out.println("capacity:" + buffer.capacity()); // 8

               System.out.println("limit:" + buffer.limit()); // 8

               System.out.println("position:" + buffer.position()); // 0


               buffer.put('a');

               buffer.put('b');

               buffer.put('c');

               System.out.println("------------------------");


               System.out.println("capacity:" + buffer.capacity()); // 8

               System.out.println("limit:" + buffer.limit()); // 8

               System.out.println("position:" + buffer.position()); // 3


               System.out.println("------------------------");

               // 切换模式  ,limit变为position的位置然后将position变为0

               buffer.flip();

               System.out.println("capacity:" + buffer.capacity()); // 8

               System.out.println("limit:" + buffer.limit()); // 3

               System.out.println("position:" + buffer.position()); // 0


               System.out.println("------------------------");

//                char ch = 0;

//                ch = buffer.get();

//                System.out.println(ch);

//                ch = buffer.get();

//                System.out.println(ch);

//                

////                System.out.println("capacity:" + buffer.capacity()); // 8

////                System.out.println("limit:" + buffer.limit()); // 3

////                System.out.println("position:" + buffer.position()); // 2

//                ch = buffer.get();

//                System.out.println(ch);

//                

//                ch = buffer.get();

//                System.out.println(ch);


               int ch = 0;

               while (buffer.hasRemaining()) {

                       ch = buffer.get();

                       System.out.println((char)ch);

               }


               System.out.println("------------------");

               buffer.clear(); // 将postion 清 0 ,将limit = capacity


               System.out.println("capacity:" + buffer.capacity()); // 8

               System.out.println("limit:" + buffer.limit()); // 8

               System.out.println("position:" + buffer.position()); // 0


               // 注意: 调用clear方法只是将读模式改为写模式,并不会清空缓冲区的数据

               System.out.println(buffer.get(1));

               System.out.println("执行绝对读取之后Buffer的position位置:" + buffer.position());

       }

}

Channel通道

* Channel原理类似于传统的流对象, FileInputStream FileOutputStream

* 但是有两个主要的区别

*         1.Channel能够将指定的部分或者全部文件映射到内存中

*                 全部映射

*                         MappedByteBuffer

*                 部分文件映射

*  2.程序如果想要读取Channel中的数据,不能够直接读写,必须经过Buffer

*  

*  Java中为Channel提供了如下常用的类

*  

*  FileChannel 和文件相关的通道

*  DatagramChannel 和UDP协议传输数据相关的通道

*  SocketChannel 和TCP协议相关的数据传输通道

*  ServerSocket 和TCP协议相关的数据传输通道

*  

*  获取FileChannel对象

*  和文件相关的普通流有哪些?

*          FileInputStream FileOutputStream RandomAccessFile

*  常用的方法

*  read() : 将Channel中的数据读取到Buffer中

*  write() : 向Buffer中写入数据

*  map(): 将channel中的数据全部或者部分映射到Buffer中

*                  inChannel.map(mode, position, size)

*                  MappedByteBuffer mappBuffer = inChannel.map(MapMode.READ_ONLY, 0, srcFile.length());

*/

CharSet字符集

Charset 理解为现实生活的编码表对象

*/

public class NIODemo05 {

       public static void main(String[] args) throws CharacterCodingException {

               // 获取当前JDK所支持的所有编码类型

//                SortedMap<String, Charset> map = Charset.availableCharsets();

//                

//                for (String key : map.keySet()) {

//                        Charset charset = map.get(key);

//                        System.out.println(charset);

//                }


               // 知道了对应JDK认可的字符集别名后,那么我们就可以来获取对应的字符集对象

               Charset charset = Charset.forName("GBK");


               // 创建编码器  编码 字符/字符串/字符数组 --> 字节

               CharsetEncoder encoder = charset.newEncoder();

               // 创建解码器  解码 上述相反

               CharsetDecoder decoder = charset.newDecoder();


               CharBuffer charBuffer = CharBuffer.allocate(10);

               charBuffer.put("abc");

               charBuffer.flip();


               ByteBuffer byteBuffer = encoder.encode(charBuffer);


               for (int i = 0; i < byteBuffer.limit(); i++) {

                       System.out.println(byteBuffer.get(i));

               }


               System.out.println(decoder.decode(byteBuffer));

       }

}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,504评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,434评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,089评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,378评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,472评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,506评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,519评论 3 413
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,292评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,738评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,022评论 2 329
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,194评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,873评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,536评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,162评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,413评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,075评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,080评论 2 352

推荐阅读更多精彩内容