IO之NIO

什么是IO流

I是指Input(输入),O是指Output(输出)。

在Java中,文件的输入和输出是通过流(Stream)来实现的,流的概念源于Unix中管道(pipe)的概念。在Unix系统中,管道是一条不间断的字节流,用来实现程序或进程间的通信,或读写外围设备、外部文件等。

一个流,必有源端和目的端,它们可以是计算机内存的某些区域,也可以是磁盘文件,甚至可以是Internet上的某个URL。对于流而言,我们不用关心数据是如何传输的,只需要向源端输入数据,向目的端获取数据即可。

流按照处理数据的单位,可以分为字节流和字符流;按照流向分为输入流和输出流(注意:输入流和输出流都是站在程序的角度参照的)。

NIO(即New IO)

JDK1.4版本开始,JDK提供了新的IO操作API, NIO提供多路(non-blocking) 非阻塞式的高伸缩性网络I/O,从而提高了效率,NIO主要有三大核心组件:Channel、Buffer和Selector,这里重点学习前两个, Selector 将在网络编程详细介绍。

Buffer

Buffer是一个抽象类,Buffer类型变量对应的对象代表一块缓冲区,ByteBuffer、CharBuffer、DoubleBuffer、FloatBuffer、IntBuffer、LongBuffer和ShortBuffer类都是Buffer抽象类的子类,其中ByteBuffer最常用。

  • ①static ByteBuffer allocate(int capacity):分配一个新的字节缓冲区,capacity为此缓存区容量大小,capacity也为当前缓冲区上限值
public class Test {
 	public static void main(String[] args) {
   		ByteBuffer bytebuffer=ByteBuffer.allocate(1024);
 	}
}
  • ②int capacity() :返回此缓冲区的容量,实际上直接将capacity成员属性值返回。
public class Test {
 	public static void main(String[] args) {
   		ByteBuffer bytebuffer=ByteBuffer.allocate(1024);
   		System.out.println(bytebuffer.capacity());
 	}
}
  • ③ByteBuffer put(byte b):将字节类型数据写入当前位置的缓冲区,然后position+1,位置从0开始
public class Test {
 	public static void main(String[] args) {
   		ByteBuffer bytebuffer=ByteBuffer.allocate(1024);
   		byte a=3;
   		bytebuffer.put(a);
 	}
}
  • ④byte[] array() :将ByteBuffer类型的数据转为byte数组
public class Test {
 	public static void main(String[] args) {
   		ByteBuffer bytebuffer=ByteBuffer.allocate(1024);
   		byte a=3;
   		bytebuffer.put(a);
   		byte[] bbuf=bytebuffer.array();
 	}
}
  • ⑤int position():返回缓冲区当前位置,实际上直接将position成员属性值返回。
public class Test {
 	public static void main(String[] args) {
   		ByteBuffer bytebuffer=ByteBuffer.allocate(1024);
   		System.out.println(bytebuffer.position());//0
   		byte a=3;
   		bytebuffer.put(a);
   		System.out.println(bytebuffer.position());//1
 	}
}
  • ⑥Buffer flip() :翻转缓冲区,将当前position值赋值给limit,并将position置零;这个方法主要防止在最后一次输出时,如果缓存区并未装满,则将position值赋值给limit即为当前缓冲区内数据量,一般搭配hasRemaining方法使用。如果没有limit属性而直接使用capacity,则会输出冗余数据。
    在这里插入图片描述
public class Test {
 	public static void main(String[] args) {
   		ByteBuffer bytebuffer=ByteBuffer.allocate(1024);
   		bytebuffer.position();//0
  	 	byte a=3;
   		bytebuffer.put(a);
   		bytebuffer.position();//1
   		bytebuffer.flip();
   		bytebuffer.position();//0
 	}
}
  • ⑦byte get()读取缓冲区当前位置的字节,然后当前位置+1
public class Test {
 	public static void main(String[] args) {
   		ByteBuffer bytebuffer=ByteBuffer.allocate(1024);
   		bytebuffer.position();
   		byte a=3;
   		bytebuffer.put(a);
  		bytebuffer.position();//1
   		bytebuffer. flip();
   		bytebuffer.position();//0
   		bytebuffer.get();
   		bytebuffer.position();//1
 	}
}
  • ⑧boolean hasRemaining():在释放缓冲区时告诉您是否已经达到缓冲区的上界
public class Test {
 	public static void main(String[] args) {
  		ByteBuffer bytebuffer=ByteBuffer.allocate(1024);
  		System.out.println(bytebuffer.position());//0
  		byte a=3;
  		bytebuffer.put(a);
  		System.out.println(bytebuffer.position());//1
  		System.out.println(bytebuffer.hasRemaining());//true
  		bytebuffer.flip();
  		bytebuffer.get();
  		System.out.println(bytebuffer.position());//1
  		System.out.println(bytebuffer.hasRemaining());//false
 	}
}

Channal

Channel是一个接口,该接口类型变量指向的对象代表一个数据传输通道,Channel对象是面向缓冲区的:数据总是从通道读取到缓冲区(Buffer类型对象),或从缓冲区(Buffer类型对象)写入到通道中

Channel接口主要实现类如下:

①FileChannel:从文件中读写数据。
②DatagramChannel:通过UDP读写网络中的数据。
③SocketChannel:通过TCP读写网络中的数据。
④ServerSocketChannel:可以监听新进来的TCP连接,像Web服务器那样,对每一个新进来的连接都会创建一个SocketChannel。

public class Test{
	public static void main(String[] args) {
  		try {
   			FileInputStream fileInputStream = new FileInputStream("D:\\timg.jpg");
   			FileChannel inputChannal = fileInputStream.getChannel();
   
   			FileOutputStream fileOutputStream = new FileOutputStream("D:\\hh.jpg");
   			FileChannel outputChannal = fileOutputStream.getChannel();
   
   			ByteBuffer buffer = ByteBuffer.allocate(1024);
   			while((inputChannal.read(buffer))!=-1) {
    				buffer.flip();
    				outputChannal.write(buffer);
    				buffer.clear();
   			}
  		} catch (Exception e) {
   			e.printStackTrace();
  		}
 	}
}
发布了101 篇原创文章 · 获赞 3 · 访问量 2219

猜你喜欢

转载自blog.csdn.net/S_Tian/article/details/104634525