Java NIO 入门(三)从理论到实践:使用NIO读写
guibin.beijing@gmail.com
概述
读和写是最基础的IO处理。从Channel中读是非常简单的,我们只要创建一个Buffer,然后要求Channel往Buffer中读数据。写也很简单,也需要创建一个Buffer,把要写的数据填充到Buffer中,然后要求Channel把Buffer中的数据写出去。
在这节中,我们学习使用JAVA程序来读写数据,顺便浏览一下NIO的主要组件(Buffer,Channel以及相关的方法)并且看看他们在读写数据时如何交互,在后面的章节中我们将依次查看每个组件的细节。
从文件中读数据
在第一个练习中,我们首先从文件中读取一些数据。如果使用老的IO,只需要简单的创建FileInputStream,然后从中读取数据。在NIO中,事情变得有些不同了,首先需要从FileInputStream中获取Channel对象,然后使用这个Channel去读文件。
在NIO系统中任何时刻执行一个读操作时,都要从Channel中读,但不是直接从Channel中读。由于所有的数据都需要通过Buffer承载,所以需首先从Channel中把数据读进Buffer。
因此,从文件中读数据一共有三步:
- 从FileInputStream中获取Channel
- 创建Buffer
- 从Channel中把数据读入Buffer
下面我们仔细看看具体时如何工作的。
三步简单的工作
第一步获取Channel。从FileInputStream中获取Channel。
FileInputStream fin = new FileInputStream( "readandshow.txt" );
FileChannel fc = fin.getChannel();
第二步创建Buffer
ByteBuffer buffer = ByteBuffer.allocate( 1024 );
最后一步,将文件内容通过Channel读入Buffer中
fc.read( buffer );
你一定发现,在这里,并没有告诉Channel把多少内容读进Buffer。在每个Buffer中都有一套完整的内部计数系统来跟踪已经读了多少数据了,Buffer中还剩多少空间。关于Buffer的计数系统在随后的“Buffer内部原理”中讲解。
写文件
使用NIO写文件和读文件非常类似。我们还是从FileOutputStream中获取Channel。
FileOutputStream fout = new FileOutputStream( "writesomebytes.txt" );
FileChannel fc = fout.getChannel();
下一步还是创建Buffer并且把数据放到Buffer中。在这种情况下数据将从一个叫做message的数组中取出,这个数组中包含了字符串ASCII码的字节。(The buffer.flip() 和 buffer.put()在后面讲解)
ByteBuffer buffer = ByteBuffer.allocate( 1024 );
for (int i=0; i<message.length; ++i) {
buffer.put( message[i] );
}
buffer.flip();
最后一步就是把Buffer写出去。
fc.write( buffer );
再次注意,我们没有必要告诉Channel总共要写多少数据,Buffer的内部计数系统会跟踪已经写了多少数据了,还剩多少空间可以使用。
边读边写
下面看看当我们把读和写结合起来会发生什么。这个练习程序的名称叫CopyFile.java,用来从一个文件拷贝全部数据到另一个文件。Copy.java包含了三个基本的操作:
- 首先创建Buffer
- 然后从源文件把数据读入Buffer
- 最后把Buffer写入目的文件
程序重复的进行读写、读写,直到文件读完。
CopyFile程序能够看到如何检查程序的状态,以及如何使用clear(),flip()方法重置Buffer,如何读数据从一个Channel到另一个Channel。
运行CopyFile例子
因为Buffer跟踪了自己的内部数据,因此CopyFile程序的内部循环非常简单,如下:
fcin.read( buffer );
fcout.write( buffer );
首先数据从输入Channel中读入Buffer,然后把数据写出到输出Channel中。因为输入和输出分别对应于两个文件,因此是两个Channel。
检查读文件的状态
下一步,当我们在拷贝时需要检查读文件的状态。当没有数据可读时即执行完毕,这个状态可以通过read()方法返回-1来判断,如下:
int r = fcin.read( buffer );
if (r==-1) {
break;
}
重置Buffer
最后,在从Channel将数据读入Buffer前调用clear()方法,相似的,在将Buffer写入输出Channel之前调用flip()方法。
buffer.clear();
int r = fcin.read( buffer );
if (r==-1) {
break;
}
buffer.flip();
fcout.write( buffer );
clear()方法重置了Buffer,使其准备好能够将读入的数据放入Buffer中。flip()方法使得Buffer准备好把Buffer中的数据写入Channel。
本文参考自
http://www.cs.brown.edu/courses/cs161/papers/j-nio-ltr.pdf
分享到:
相关推荐
在本文中,我们将深入探讨Java NIO的基本概念、组件以及如何在实际编程中使用。 一、Java NIO概述 Java NIO并非简单的输入输出API的替代,而是提供了一种新的I/O模型。传统IO基于流(Stream)进行数据读写,而NIO基于...
IBM的NIO入门教程通常会涵盖这些基础概念,并通过实例演示如何使用NIO进行实际的I/O操作。教程可能还会深入讲解NIO的高级特性,如scatter/gather(分散/聚集)读写,以及如何使用`Selector`进行多路复用。通过学习这...
3. **读写操作**:通过通道与缓冲区交互进行数据传输,如从通道读取数据到缓冲区,或者从缓冲区写入数据到通道。 4. **使用选择器**:如果有多条通道需要管理,可以注册它们到选择器,然后通过选择器来监听和选择...
Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java从1.4版本开始引入的一种I/O模型,旨在提供一种更高效、更具控制力的I/O操作方式。与传统的-blocking I/O(阻塞I/O)相比,NIO的关键在于它...
**NIO(New Input/Output)是Java编程语言中用于替代标准I/O(BIO,Blocking I/O)的一组API,它提供了非阻塞式的I/O操作方式,极大地提升了Java在处理I/O密集型应用时的性能。NIO在Java 1.4版本中被引入,之后在...
《IBM Java文档库 NIO 入门》这篇教程主要针对的是Java 1.4引入的New Input/Output (NIO)库,这是一个重要的更新,旨在提高Java程序的I/O性能,特别是面向块的I/O操作。NIO弥补了传统I/O(基于java.io.*包)的不足,...
本教程旨在为读者提供一个全面的NIO入门指南,不仅涵盖了NIO的基础理论知识,还包括了实际编程中使用到的代码示例。 在学习NIO之前,读者需要掌握Java语言的一些基本概念,包括类、继承、包等。此外,如果读者对...
Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java从1.4版本开始引入的一种I/O模型,旨在提供一种更高效、更具控制力的I/O操作方式。与传统的 Blocking I/O(同步阻塞I/O)相比,NIO的核心特点...
- **Java NIO.2 (New IO 2)**: 从Java 7开始引入,增加了对文件属性、异步I/O、文件锁定等的支持。 - **Java Channels and Buffers** IBM教程: 提供的`.chm`文件可能包含详细的NIO通道和缓冲区的使用示例和解析,...
《NIO入门》一书是理解Java NIO(New Input/Output)的重要参考资料,NIO在Java编程中扮演着至关重要的角色,特别是在处理高并发、大数据传输等场景下。本PDF文档将引领读者深入理解这一核心概念。 NIO,全称New ...
- **直接缓冲区**:NIO 还支持直接缓冲区,这是一种特殊的缓冲区,数据可以直接从它写入或读出到物理内存中,从而避免了 Java 堆上的额外拷贝操作。 #### 三、NIO 的编程实践 - **缓冲区的基本操作**:在使用 ...
本入门文档及示例代码旨在帮助开发者快速理解并掌握Java NIO的基本概念和用法。 一、NIO基础概念 1. **通道(Channels)**:NIO的核心组件之一,它是连接到数据源(如文件、套接字)的通道,可以读写数据。常见的...
### Java NIO 入门详解 #### 一、NIO 的背景与意义 **NIO (New Input/Output)** 是 Java 在 JDK 1.4 中引入的一个全新的输入输出库,旨在改进原有的 IO 库(主要位于 `java.io.*` 包中)的性能和功能。传统的 Java...
**NIO(New Input/Output)**,全称为New IO,是Java中的一种I/O模型,它是相对于传统的BIO(Blocking I/O)模型而言的。NIO在Java 1.4版本引入,主要目的是为了提高在高并发环境下的I/O性能。与BIO不同,NIO是非...