NIO(即 New IO)

JDK1.4版本开始,JDK提供了新的IO操作API NIO提供多路(non-blocking) 非阻塞式的高伸缩性网络I/O,从而提高了效率,NIO主要有三大核心组件:ChannelBufferSelector,这里重点说前两个。

Buffer

Buffer是一个抽象类Buffer类型变量对应的对象代表一块缓冲区ByteBufferCharBufferDoubleBufferFloatBufferIntBufferLongBufferShortBuffer类都是Buffer抽象类的子类,其中ByteBuffer最常用。

ByteBuffer常用方法:

  1. static ByteBuffer allocate(int capacity):分配一个新的字节缓冲区;
  2. int capacity() :返回此缓冲区的容量;
  3. ByteBuffer put(byte b):将字节类型数据写入当前位置的缓冲区,然后当前位置+1,位置从0开始;
  4. byte[] array() :将ByteBuffer类型的数据转为byte数组;
  5. int position():返回缓冲区当前位置;
  6. Buffer flip() ):翻转缓冲区,将position置零;
  7. boolean hasRemaining():当前位置是否超出了极限范围,参见源码;
  8. byte get()读取缓冲区当前位置的字节,然后当前位置+1;
  9. Buffer clear():清除缓冲区,但该方法并不会实际删除数据,位置归零。

以下是上面几种方法的部分方法的应用和输出效果说明代码:

import java.nio.ByteBuffer;

public class Test {

	public static void main(String[] args) {
		ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
		System.out.println(byteBuffer.capacity());
		System.out.println(byteBuffer.position());
		byte a = 1;
		byteBuffer.put(a);
		System.out.println(byteBuffer.position());
	}	
}

输出结果:
1024
0
1

注意:使用 put 方法会使当前位置(position) +1

import java.nio.ByteBuffer;

public class Test {

	public static void main(String[] args) {
		ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
		byte a = 9;
		byteBuffer.put(a);
		System.out.println(byteBuffer.position());
		byteBuffer.flip();
		System.out.println(byteBuffer.position());
		//get方法也会使当前位置 +1
		System.out.println(byteBuffer.get());
		System.out.println(byteBuffer.position());
	}	
}

输出结果:
1
0
9
1

flip 方法是将当前位置(position)重置为 0;get 方法是获取当前位置上的信息,并且使用该方法会使当前位置 +1;如上:

clear 方法则是将 byteBuffer 上的数据从意义上清零;就是虽然系统不是删除 byteBuffer 上的数据,但是从使用者的角度是和清空数据一样的效果;注意:这个方法和 flip 有着本质上的区别,flip 是把当前位置(position)置为 0;而 clear 则是将数据清空。

import java.nio.ByteBuffer;

public class Test {

	public static void main(String[] args) {
		ByteBuffer byteBuffer = ByteBuffer.allocate(3);
		for(int i=0;i<3;i++) {
			byteBuffer.get();
			System.out.println(byteBuffer.hasRemaining());
		}
	}	
}

输出结果:
true
true
false

hasRemaining 方法类似于数组的判断是否越界,但是与之不同的是,当 position 指到 capacity 缓冲区容量最大值时即为 false,而不是大于容量最大值时为 false;

Channel

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

Channel 接口主要实现类如下:
  • FileChannel:从文件中读写数据。

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

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

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

只能 通过调用 FileInputStream FileOutputStream 类中 getChannel 方法获取 FileChannel 对象, FileChannel 类常用 方法如下:
 

1、int read(ByteBuffer dst)

从通道的当前文件位置开始将数据读取到缓冲区,然后以实际读取的字节数更新文件位置;返回实际读取的字节数,如果已达到通道末尾, 则返回-1

2、void close()

关闭通道。

import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class Test {

	public static void main(String[] args) {
		FileInputStream fileInputStream = null;
		FileChannel fileChannel = null;
		try {
			fileInputStream = new FileInputStream("D:\\1.txt");
			fileChannel = fileInputStream.getChannel();
			ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
			while(fileChannel.read(byteBuffer)!=-1) {
				byteBuffer.flip();
				String data = new String(byteBuffer.array());
				System.out.println(data);
				byteBuffer.clear();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			if(fileInputStream!=null) {
				try {
					fileInputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(fileChannel!=null) {
				try {
					fileChannel.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}	
}

byteBuffer.array:ByteBuffer类型的数据转为byte数组;

输出结果如下:

1.txt 文件内容如下:

3、int write(ByteBuffer src)

从通道的当前文件位置开始将缓冲区中数据写入通道,然后文件位置用实际写入的字节数更新。

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class Test {

	public static void main(String[] args) {
		FileInputStream fileInputStream = null;
		FileChannel inputChannel = null;
		
		FileOutputStream fileOutputStream = null;
		FileChannel outputChannel = null;
		try {
			fileInputStream = new FileInputStream("D:\\1.txt");
			inputChannel = fileInputStream.getChannel();
			
			fileOutputStream = new FileOutputStream("D:\\2.txt");
			outputChannel = fileOutputStream.getChannel();
			
			ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
			while(inputChannel.read(byteBuffer)!=-1) {
				byteBuffer.flip();
				outputChannel.write(byteBuffer);
				byteBuffer.clear();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			if(fileInputStream!=null) {
				try {
					fileInputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(inputChannel!=null) {
				try {
					inputChannel.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(fileOutputStream!=null) {
				try {
					fileOutputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(outputChannel!=null) {
				try {
					outputChannel.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}	
}

 2.txt 文件:

 
 
发布了99 篇原创文章 · 获赞 3 · 访问量 1192

猜你喜欢

转载自blog.csdn.net/qq_44971038/article/details/104669125
今日推荐