Java新IO

作者: 黎繁介 | 来源:发表于2018-07-11 18:57 被阅读107次

新IO流概述

        自JDK1.4开始,java提供了一系列新的的输入/输出流,统称为新IO(NewIO),与以往IO流处理不同的是(以往的IO流处理都是通过字节的移动来处理,即一个一个字节的操作),而新IO流是通过内存映射文件来进行操作的(即将文件或一段文件区域映射到内存中),通过访问内存就像访问文件一样,效果就是使得输出/输出操作更快。

        Java相关包:

        →java.nio包:主要提供了一些和Buffer相关的类。

        →java.nio.channels包:主要包括Channel和Selector相关的类。

        →java.nio.charset包:主要包含和字符集相关的类。

        →java.nio.channels.spi包:主要包含Channel服务的类。

        →java.nio.charset.spi包:主要包含和Charset服务的类。

新IO中有两个核心:Channel(通道)和 Buffer(缓冲)


一、Buffer

        Buffer相当于数组,可以保存多个类型的数据,为抽象类。

在Buffer中三个重要的概念:

        →容量(Capacity):缓冲区的最大容量,该容量不能为负数,不能更改。

        →界限(limit):第一个不能够被读取和写入的位置索引,该位置索引后的内容不能够读取,也不能够写入。

        →位置(position):用于指明下一个可以被读取或写入的缓冲区索引位置(相当于IO流中的记录指针),默认状态下为0,然后读取/写入多少数据就后移多少位置。

使用Buffer步骤:

        这些Buffer子类无构造器,所以只能以 static XxxBuffer allocate(int capacity):创建一个大小为capacity的XxxBuffer对象。方法创建。

        Buffer用于装载数据,然后读取数据。对象初始化时,position为0,limit等于capacity。

        装入数据 --> position移动相应的大小 --> 装入数据结束,调用flip方法(将limit设置到position位置,position设为0),为读取数据准备 --> 读取数据 --> position移动相应的大小,直到读取到limiit读取完成 --> 调用clear方法(将limit设置到capacity位置,position设置为0),为下次装入数据做准备

常用方法:

        →public final Buffer flip():反转此缓冲区。limit设置到position位置 然后position设为0. 如果标记mark存在,则抛弃。

        →public final Buffer clear():清理此缓冲区。limit设置到capacity位置,position位置设为0,丢弃mark。

        →public final int capacity():返回此Buffer的capacity大小。

        →public final int remaining():返回当前位置position和limit之间的元素个数。

        →public final boolean hasRemaining():判断当前位置position和limit之间是否有元素可以处理。

        →public final int position():返回此Buffer当前位置position。

        →public final Buffer position(int newPosition):设置新位置position,返回一个改变position后的Buffer对象。

        →public final Buffer reset():将位置position转到mark所在的位置。

        →public final Buffer rewind():将位置position设置为0,并取消设置的mark。

        →public final Buffer mark():设置该Buffer中mark的位置。(mark只能在0和position之间选择)

Buffer所有子类的两个重要方法:

        put(放入数据)和get(取出数据)方法:

        →使用相对方法(Relative):从Buffer当前位置读取/写入数据,position按照处理的元素个数增加。

        →使用绝对方法(Absolute):直接根据索引值来读取/写入数据,该形式不会影响posiiton的值。

下面以CharBuffer为例子:

CharBufferTest类 运行结果

小提示:使用allocate创建的Buffer都是普通的Buffer,多用于生存期短,用完一次就扔掉。而ByteBuffer中提供了allocateDirect创建的Buffer,成本高,适用于生存期长,使得IO操作更快!


二、Channel

        通道,顾名思义,与流不同的是(流只能进行单向读或写的操作,因为每一种流只能继承一种InputStream或OutputStream等基类),通道是双向的,即可以读或写亦可以同时读写的操作。不过我们不是直接通过对通道进行读与写的操作,而是使用缓冲区Buffer,即要Channel中读取数据,需要先用Buffer从Channel中取出一些数据,然后在从Buffer中来读取数据,反之向Channle中写入数据也是如此,先向Buffer中写入一些数据,然后程序使用Buffer向Channel写入数据。

Java中重要的一些通道的实现:

        FileChannel:从文件中读写数据

        DatagramChannel:通过UDP读写网络中的数据

        SocketChannel:通过TCP读写网络中的数据

        ServerSocketChannel:可以监听新进来的TCP连接,像Web服务器那样。对每一个新进来的连接都会创建一个SocketChannel。

下面以FileChannel作为例子:

注意:文件通道总是阻塞式的,即FileChannel是线程安全的,在一个线程对他的对象进行操作的时候,其他线程必须等待。

还有一点,当有2个通道,其中一个通道是FileChannel的时候,通道之间是可以传输数据的!通过FileChannel的两个方法:

transferFrom和transferTo"


三、编码集和Charset

        我们都知道对于文件文本(图片、音频等暂且不谈),也就是字符这些我们肉眼都能够看懂,但是对于计算机,它只认识0和1,那该怎么办呢,于是便有了编码,就是将这些字符转化成一系列的二进制字节序列让计算机能够识别(不同的字符有着相应的二进制的字节序列),相反就有了解码,能够让我们看的懂(不费劲)。

        同时,我们知道计算机是外国人发明的,由于使用的是英语,so使用英语的话不必考虑这些,但是发展是普及的,世界上这么多国家,每个国家的语言是不一样的,尤其是我们华夏之国,汉子那可不是区区26个字母能比的😋!于是经过人们不断地努力,一系列的字符集出现了。以下是我们国人常用的字符集提供编码与解码:

·GBK:    简体中文字符集。

·BIG5:    繁体中文字符集。

·ISO-8859-1:    ISO拉丁字母表No.1,也叫做ISO-LATIN-1。

·UTF-8:    8位UCS转化格式。

·UTF-16BE:    16位UCS转换格式,BigEndian(最低位存放最高位字节)字节顺序。

·UTF-16LE:    16位UCS转换格式,LittleEndian(最高位存放最低位字节)字节顺序。

·UTF-16:    16位UCS转换格式,字节顺序由可选的字节顺序标记。

在Java中,提供了Charset供我们来进行编码和解码,用法如下:

        →public    static    Charset    forName(String    charsetName):创建Charset对象,参数charsetName是相应字符集名称。

        →public    final    ByteBuffer    encode(CharBuffer cb):将CharBuffer中的字符序列转换成字节序列的便捷方法。

        →public    final    ByteBuffer    encode(String    str):将String中的字符序列转换成字节序列的便捷方法。

        →public final    CharBuffer    decode(ByteBuffer bb):将ByteBuffer中的字节序列转换成字符序列的便捷方法。

或者获取对象对应的编码器和解码器来进行操作:

调用Charset对象的newEncoder()返回一个CharsetEncoder对象(使用encode方法将字符序列转化成字节序列),或调用newDecoder()返回一个CharsetDecoder对象(使用decode方法将字节序列转化成字符序列)。下面以GBK编码集作为例子:

运行结果:

另外String类提供了getBytes(String charset)方法将字符序列转换成字节序列(使用特定的字符集,因平台而异);String类的构造器提供了将字节序列转字符序列的功能:new String(byte[] bytes,String encoding),

其本质是将其它编码集朝Unicode字符集转换,其中有涉及到兼容的问题。



相关文章

  • 3 java的IO

    java nio Java的IO体系:旧IO新IO:nio,用ByteBuffer和FileChannel读写ni...

  • Java常用包的主要作用

    java.io io流相关操作java.nio 新io操作java.lang 核心功能包,线程,System,基本...

  • Java NIO 概述

    Java NIO 概述 Java NIO(新的IO)是Java的替代IO API(来自Java 1.4),这意味着...

  • 2.1.3 NIO非阻塞网络编程三大理念

    Java NIO 始于Java 1.4,提供了新的Java IO操作非阻塞APi。 用意是替代Java IO 和 ...

  • Java - NIO网络编程

    JAVA NIO 始于Java1.4, 提供了新的Java IO 操作非阻塞API。目的是替代Java IO 和 ...

  • Java新IO

    新IO流概述 自JDK1.4开始,java提供了一系列新的的输入/输出流,统称为新IO(NewIO),与以往IO流...

  • Java NIO

    Java NIO (New IO,Non-Blocking IO)是从Java 1.4版本开始引入的一套新的IO ...

  • NIO

    Java NIO 简介 Java NIO(New IO)是从 Java 1.4 版本开始引入的一个新的 IO AP...

  • Java 并发基础之 Java NIO 详解

    Java NIO(Java New IO)是从 Java 1.4 版本开始引入的一个新的 IO API,可以替代标...

  • Java NIO学习笔记-通道&缓冲区

    Java NIO是什么 Java NIO( New IO) 是从Java 1.4版本开始引入的一个新的IO API...

网友评论

      本文标题:Java新IO

      本文链接:https://www.haomeiwen.com/subject/kyjdyftx.html