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)。
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。如果应用程序打开了许多连接,但每个连接上的流量很低,那么这会很方便。例如在聊天服务器中。
如果要使用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()方法的具体含义及作用在下篇笔记中更新。
更多内容:我的博客
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决