1. 首页
  2. 开发

java从零开始系列(八)非阻塞IO(NIO)介绍

JavaNIO简介

  • NIO提供了一个全新的底层I/O模型,与最初的java.io包中面向流的概念不同,NIO中采用了面向块的概念。这意味着I/O操作以大的数据块为单位进行,而不是一次一个字节或字符进行。采用这样的操作方式java的I/O性能有很大提高,但也牺牲了java操作的简单性。
  • NIO提供与平台无关的非阻塞I/O。与面向线程的、阻塞式I/O方式比较,多道通信、非阻塞I/O技术可以使应用程序更有效地处理大量连接的情况。
  • JavaNIO中使用Buffer和Channel支持以上的操作。

Buffer
    NIO中所有的操作都要使用到缓冲区处理,且所有的读写操作都是通过缓冲区完成的。缓冲区(buffer)是一个线性的、有序的数据集,只能容纳某种特定的数据类型。

缓冲类型
    在NIO中针对每一种基本数据类型都有一种对应的缓冲操作类:
     序号 缓冲区类               描述

  • Java.nio.ByteBuffer 存储字节
  • Java.nio.CharBuffer 存储字符
  • Java.nio.ShortBuffer 存储短整数
  • Java.nio.IntBuffer  存储整数
  • Java.nio.LongBuffer 存储长整数
  • Java.nio.FloatBuffer 存储单精度浮点数
  • Java.nio.DoubleBuffer 存储双精度浮点数

NIO中常用方法方法 描述

  • Public static 缓冲区类型 allocate(int capacity)                        分配缓冲区空间
  • Public 基本数据类型 get()                                                   得当前位置的内容
  • Public 基本数据类型 get(int index)                                       取得指定位置的内容
  • Public 缓冲区类型 put(基本数据类型 x)                                  写入指定基本数据类型的数据
  • Public final 缓冲区类型 put(数据类型[] src)                             写入一组指定的基本数据类型的数据
  • Public final 缓冲区类型 put(数据类型[] src int offset,int length) 写入一组指定的基本数据类型的数据
  • Public 缓冲区类型 slice()                                                     创建子缓冲区,其中一部分与原缓冲区共享数据
  • Public 缓冲区类型 asReadOnlyBuffer()                                   将缓冲区设置为只读缓冲区

NIO中缓冲区操作

import java.nio.IntBuffer;
public class  BufferDemo1 
{
	public static void main(String[] args) 
	{
		IntBuffer buf=IntBuffer.allocate(10);
		System.out.println("1、写入数据之前的position、limit和capacity:");
		System.out.println("position="+buf.position+",limit="+buf.limit+",capacity="+buf.capacity);
	}
}

在缓冲区中可以使用3个值表示缓冲区的状态:

  • Position:表示下一个缓冲区读取或写入的操作指针,当向缓冲区中写入数据时此指针就会改变,指定永远放到写入的最后一个元素之后。
  • Limit 表示还有多少数据需要存取或者读取,position<=limit
  • Capacity:表示缓冲区的最大容量,limit<=capacity.

NIO中创建子缓冲区
    使用各个缓冲区类的slice()方法从一个缓冲区中创建一个新的子缓冲区,子缓冲区与原缓冲区的部分数据可以共享。

NIO中创建只读缓冲区

    只需要使用到缓冲区中的内容,当不希望其内容被修改,则可以通过asReadOnlyBuffer()方法创建一个只读缓冲区,但是创建完毕后,此缓冲区不能变为可写状态。

NIO中创建直接缓冲区
    在缓冲区操作类中,只有ByteBuffer可以创建直接缓冲区,这样Java虚拟机将尽最大努力直接对其执行本机的IO操作。

通道
    NIO中的通道(Channel)可以用来读取和写入数据,通道类似于之前的输入/输出流,但是程序不会直接操作通道,所有的内容都是先读到或写入到缓冲区中,在通过缓冲区中取得或写入的。通道是双向操作的,既可以完成输入也可以完成输出。

FileChannel
    NIO中的FileChannel是Channel的子类,可以进行文件的读写操作。可以依靠FileInputStream、或FileOutputStream类中的getChannel()方法取得输入或输出的通道。

    

内存映射(MappedByteBuffer)
    NIO中内存映射可以把文件映射到内存中,这样文件内的数据就可以用内存读写指令来访问,而不是用InputStream或OutputStream这样的I/o操作类,采用此方式读取文件的速度是做快的。使用FileChannel类提供的map()方法。
    Map()方法在使用时要指定映射模式,在内存映射中提供三种模式。
    

文件锁(FileLock)
    Java NIO中提供了文件锁的功能,这样当一个线程将文件锁定之后,其他线程是无法操作此文件的,要想进行文件的锁定操作,则要使用FileLock类完成,FileChannel类中提供FileLock类的实例化对象方法:

    

文件锁定方式:

  • 共享锁:允许多个线程进行文件的读取操作
  • 独占锁:只允许一个线程进行文件的读写操作。
收藏

暂无评论

登录后可以进行评论。没有账号?马上注册