Java NIO 笔记01

Java NIO 简介

更多内容:我的博客
Java NIO 由以下几个核心组成:

  • Channels
  • Buffers
  • Selectors

Java NIO 除了上面三个还有很多组件,但是最核心的还是上面这三个,所以搞懂上面三个的含义及用法是学习Java NIO的重点。其余组件,例如Pipe和FileLock只是与三个核心组件结合使用的实类。

Channels 与 Buffers

通常,在NIO中所有的IO都是以一个Channel开始。这里的Channel可以理解为像流的一个概念。然后我们可以从Channel中读取数据到Buffer中,数据也可以从Buffer区写入到Channel中。这个流是双向的流,不像普通IO中stream的概念,普通IO中的Stream是单向的(InputStream or OutputStream)。

Channels and Buffers

Java NIO 中主要的Channel实例:

  • FileChannel
  • DatagramChannel
  • SocketChannel
  • ServerSocketChannel

上面这些涵盖了UDP+TCT的网络IO和文件IO。

Java NIO 中有一下主要的Buffer:

  • ByteBuffer
  • CharBuffer
  • DoubleBuffer
  • FloatBuffer
  • IntBuffer
  • LongBuffer
  • ShortBuffer

上面这些Buffer涵盖了我们可以通过IO发送的基本数据类型:byte, short, int, long, float, double 和 characters。

Selectors

Selector允许单个线程处理多个Channel。如果应用程序打开了许多连接,但每个连接上的流量很低,那么这会很方便。例如在聊天服务器中。

Selectors

如果要使用Selector的话需要我们将Channel注册给Selector。然后调用它的select()方法,此方法将阻塞,直到注册的Channel之一有了已准备事件(ready event)。一旦方法返回,线程就可以处理这些事件。

Java NIO Channel

Java NIO 的 Channel 类似流,但有一下不同之处:

  • Channel 是双向的,既可以写入也可以读出,而流是单向的——读或写
  • Channel 可以异步的读取和写入
  • Channel 总是读取和写入一个Buffer
Channel 的实现
  • FileChannel:从文件读取或写入
  • DatagramChannel:可以通过UDP在网络中读写数据
  • SocketChannel:可以通过TCP在网络上读写数据
  • ServerSocketChannel:允许侦听传入的TCP连接,就想Web服务器一样,对于每个传入的连接,都会创建一个SocketChannel
简单实例

下面是一个简单的例子:使用FileChannel读取一些数据到Buffer中。

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.time.LocalDateTime;

public class FileChannelTest {
	
	private final static String filePath = "C:\\temp\\fileChannelTest.txt";

	public static void main(String[] args) {
		readFile(filePath);
	}
	
	public static void readFile(String filePath) {
		try(RandomAccessFile file = new RandomAccessFile(filePath,"rw"); FileChannel channel = file.getChannel()){
			ByteBuffer buffer = ByteBuffer.allocate(48);
			System.out.println("file size is :"+channel.size()+"byte");
			int readStatusCount = channel.read(buffer);
			while(readStatusCount != -1) {
                //注意这里调用flip()方法
				buffer.flip();
				while(buffer.hasRemaining()) {
					System.out.print((char)buffer.get());
				}
				buffer.clear();
				readStatusCount = channel.read(buffer);
			}
		} catch(IOException e) {
			e.printStackTrace();
		}
	}
}

运行结果:

file size is :24byte
https://www.huhailon.vip

flip()方法的具体含义及作用在下篇笔记中更新。
更多内容:我的博客

posted @   胡海龙  阅读(24)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
www.huhailong.vip
点击右上角即可分享
微信分享提示