Java笔记(18)NIO流

本文介绍了Java NIO的基础知识,包括NIO流的特性,与传统IO流的区别,核心组成部分如通道(Channels)、缓冲区(Buffers)和选择器(Selectors)。NIO提供非阻塞的读写,通过通道读取和写入数据到缓冲区,且通道是双向的。Selector允许单线程处理多个通道的事件,提高了并发性能。此外,JDK7引入了方便的文件操作类。

Java笔记(18)NIO

1.NIO流

NIO是JDK1.4后出的一个新的流体系,它的实现原理与原来的IO流有很大的不同,可以通过将文件区域映射到内存中的方式来实现传输,因此它的效率要比IO流快很多。IO流与NIO的区别在于:IO是面向流的,而NIO是面向缓冲区的,并且在读写过程中IO流是阻塞式,而NIO可以通过选择器选择通道,是非阻塞式的。

Java NIO由以下几个核心部分组成

  • Channels(通道)
  • Buffers(缓冲区)
  • Selectors(选择器)

Channels和Buffers (通道与缓冲区)
标准IO流通过字节流和字符流进行操作,而NIO通过通道和缓冲区对数据进行操作,在NIO中,数据总是从通道读入缓冲区中,或从缓冲区中写入通道。并且在NIO中,线程是非阻塞的,即在通道读取数据的时候,你还可以让线程去干其他的事情,不必像IO流中要一直等到数据读写完毕;

Channel是一个对象,可以通过它读取和写入数据。可以把它看做IO中的流。但是它和流相比还有一些不同:

  • Channel是双向的,既可以读又可以写,而流是单向的
  • Channel可以进行异步的读写
  • 对Channel的读写必须通过buffer对象

在Java NIO中Channel主要有如下几种类型:
    FileChannel:从文件读取数据的
    DatagramChannel:读写UDP网络协议数据
    SocketChannel:读写TCP网络协议数据
    ServerSocketChannel:可以监听TCP连接

其他的Channel类和Buffer可以通过API查看,具体的就不再列出;

Selector(选择器)
Selector允许单线程处理多个Channels,用于监听多个通道的事件(比如:连接打开,数据到达)。因此,单个的线程可以监听多个数据通道。

NIO实例:

1.读数据到缓冲区
	//1.获取Channel通道对象,需要通过一个流对象获取
	FileInputStream fin = new FileInputStream( "test.txt" );
	FileChannel fc = fin.getChannel(); 
	//2.创建缓冲区
	ByteBuffer buffer = ByteBuffer.allocate(1024);
	//3.从通道读取数据到缓冲区
	fc.read(buffer);

-------------------------------------------------------------------------
2.读写结合,复制文件
public static void copyFileNIO(String src,String dest) throws IOException{
    //声明源文件和目标文件
    FileInputStream fis=new FileInputStream(new File(src));
    FileOutputStream fos=new FileOutputStream(new File(dest));
    //获得传输通道channel
    FileChannel inChannel=fis.getChannel();
    FileChannel outChannel=fos.getChannel();
    //获得容器buffer
    ByteBuffer buffer=ByteBuffer.allocate(1024);
    while(true){
    	//判断是否读完文件,读到最后一个字节read方法会返回-1
        int eof =inChannel.read(buffer);
        if(eof==-1){
             break;  
         }
        //反转缓冲区,即将缓冲区当前位置重设为0
        buffer.flip();
        //开始写
        outChannel.write(buffer);
        //写完要清除缓冲区,使得下一次写入的数据重新从缓冲区最开始写入
        buffer.clear();
    }
	inChannel.close();
	outChannel.close();
	fis.close();
	fos.close();
}     
//除此外NIO中还可以通过transferTo方法直接将一个通道的字节写到另一个通道,具体可查看API自行体验

此外更多NIO类可以通过API学习掌握,由于目前学习开发中很少使用NIO类,大多都是传统的IO流方式实现读写传输,所以就不再一一列举介绍。

在JDK7还出现了NIO的一些方便进行文件操作的类,如Path,Paths,Files类等,大家可以通过网络和API查看具体使用和原理。

### 关于尚硅谷 Java NIO 学习笔记或 PDF 的查找 目前,尚未提供具体的尚硅谷 Java NIO 学习笔记或 PDF 文件的相关链接。然而,可以通过以下方式获取相关资源: 1. **官方渠道** 尚硅谷作为一家知名的 IT 教育机构,通常会在其官方网站或其他授权平台上发布课程资料。建议访问尚硅谷官网,搜索与 Java NIO 相关的课程,并下载配套的学习资料[^1]。 2. **第三方平台** 许多教育分享网站可能提供了尚硅谷的 Java NIO 学习笔记或视频教程。可以在诸如 优快云、GitHub 或者百度网盘等平台上尝试搜索关键词“尚硅谷 Java NIO”,找到对应的 PDF 或其他格式的文档[^2]。 3. **核心知识点总结** 如果暂时无法获得完整的 PDF 资料,以下是基于 Java NIO 的基础知识整理,供参考: #### 什么是 NIOJava NIO 是 New IO 的缩写,它是从 JDK 1.4 版本开始引入的一套新的 I/O API。相比传统 I/O,Java NIO 提供了更高效的非阻塞模式以及缓冲区机制。它主要包括以下几个部分: - Buffer(缓冲区) - Channel(通道) - Selector(选择器) #### 核心组件详解 - **Buffer**: 数据容器,用于存储不同类型的字节数据。常用的方法包括 `flip()`、`clear()` 和 `rewind()`. 使用时需注意缓冲区的状态管理[^5]。 ```java ByteBuffer buffer = ByteBuffer.allocate(1024); buffer.put((byte) 'A'); buffer.flip(); while (buffer.hasRemaining()) { System.out.print((char) buffer.get()); } ``` - **Channel**: 类似于的概念,但支持双向读写操作。常见实现包括 `FileChannel` 和 `SocketChannel`. ```java try (RandomAccessFile file = new RandomAccessFile("example.txt", "rw"); FileChannel channel = file.getChannel()) { ByteBuffer buf = ByteBuffer.allocate(1024); int bytesRead = channel.read(buf); // 从通道读取数据到缓冲区 buf.flip(); // 切换为读模式 while (buf.hasRemaining()) { System.out.print((char) buf.get()); } } catch (IOException e) { e.printStackTrace(); } ``` - **Selector**: 多路复用的关键工具,允许单线程处理多个 Channel。适用于高并发场景中的网络通信[^4]. #### 如何验证学习效果? 通过编写简单的代码测试对 NIO 的理解程度。例如,利用 `FileChannel` 实现文件拷贝功能: ```java import java.io.*; import java.nio.channels.FileChannel; public class FileCopyExample { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("source.txt"); FileOutputStream fos = new FileOutputStream("destination.txt"); FileChannel sourceChannel = fis.getChannel(); FileChannel destChannel = fos.getChannel(); long bytesTransferred = sourceChannel.transferTo(0, sourceChannel.size(), destChannel); sourceChannel.close(); destChannel.close(); fis.close(); fos.close(); System.out.println(bytesTransferred + " bytes copied."); } } ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值