`
wutao8818
  • 浏览: 615755 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

NIO 中的读和写

    博客分类:
  • io
IBM 
阅读更多

FROM  IBM : developerWorks 中国网站

读和写是 I/O 的基本过程。从一个通道中读取很简单:只需创建一个缓冲区,然后让通道将数据读到这个缓冲区中。写入也相当简单:创建一个缓冲区,用数据填充它,然后让通道用这些数据来执行写入操作。

在本节中,我们将学习有关在 Java 程序中读取和写入数据的一些知识。我们将回顾 NIO 的主要组件(缓冲区、通道和一些相关的方法),看看它们是如何交互以进行读写的。在接下来的几节中,我们将更详细地分析这其中的每个组件以及其交互。

从文件中读取

在我们第一个练习中,我们将从一个文件中读取一些数据。如果使用原来的 I/O,那么我们只需创建一个 FileInputStream 并从它那里读取。而在 NIO 中,情况稍有不同:我们首先从 FileInputStream 获取一个 FileInputStream 对象,然后使用这个通道来读取数据。

在 NIO 系统中,任何时候执行一个读操作,您都是从通道中读取,但是您不是 直接 从通道读取。因为所有数据最终都驻留在缓冲区中,所以您是从通道读到缓冲区中。

因此读取文件涉及三个步骤:(1) 从 FileInputStream 获取 Channel,(2) 创建 Buffer,(3) 将数据从 Channel 读到 Buffer 中。

现在,让我们看一下这个过程。

三个容易的步骤

第一步是获取通道。我们从 FileInputStream 获取通道:


FileInputStream fin = new FileInputStream( "readandshow.txt" );
FileChannel fc = fin.getChannel();


下一步是创建缓冲区:


ByteBuffer buffer = ByteBuffer.allocate( 1024 );


最后,需要将数据从通道读到缓冲区中,如下所示:


fc.read( buffer );


您会注意到,我们不需要告诉通道要读 多少数据 到缓冲区中。每一个缓冲区都有复杂的内部统计机制,它会跟踪已经读了多少数据以及还有多少空间可以容纳更多的数据。我们将在 缓冲区内部细节  中介绍更多关于缓冲区统计机制的内容。

写入文件
在 NIO 中写入文件类似于从文件中读取。首先从 FileOutputStream 获取一个通道:


FileOutputStream fout = new FileOutputStream( "writesomebytes.txt" );
FileChannel fc = fout.getChannel();


下一步是创建一个缓冲区并在其中放入一些数据 - 在这里,数据将从一个名为 message 的数组中取出,这个数组包含字符串 "Some bytes" 的 ASCII 字节(本教程后面将会解释 buffer.flip() 和 buffer.put() 调用)。


ByteBuffer buffer = ByteBuffer.allocate( 1024 );

for (int i=0; i      buffer.put( message[i] );
}
buffer.flip();


最后一步是写入缓冲区中:


fc.write( buffer );


注意在这里同样不需要告诉通道要写入多数据。缓冲区的内部统计机制会跟踪它包含多少数据以及还有多少数据要写入。

读写结合

下面我们将看一下在结合读和写时会有什么情况。我们以一个名为 CopyFile.java 的简单程序作为这个练习的基础,它将一个文件的所有内容拷贝到另一个文件中。CopyFile.java 执行三个基本操作:首先创建一个 Buffer,然后从源文件中将数据读到这个缓冲区中,然后将缓冲区写入目标文件。这个程序不断重复 — 读、写、读、写 — 直到源文件结束。

CopyFile 程序让您看到我们如何检查操作的状态,以及如何使用 clear() 和 flip() 方法重设缓冲区,并准备缓冲区以便将新读取的数据写到另一个通道中。

运行 CopyFile 例子

因为缓冲区会跟踪它自己的数据,所以 CopyFile 程序的内部循环 (inner loop) 非常简单,如下所示:


fcin.read( buffer );
fcout.write( buffer );


第一行将数据从输入通道 fcin 中读入缓冲区,第二行将这些数据写到输出通道 fcout 。

检查状态

下一步是检查拷贝何时完成。当没有更多的数据时,拷贝就算完成,并且可以在 read() 方法返回 -1 是判断这一点,如下所示:


int r = fcin.read( buffer );

if (r==-1) {
     break;
}

 


 

重设缓冲区

最后,在从输入通道读入缓冲区之前,我们调用 clear() 方法。同样,在将缓冲区写入输出通道之前,我们调用 flip() 方法,如下所示:


buffer.clear();
int r = fcin.read( buffer );

if (r==-1) {
     break;
}

buffer.flip();
fcout.write( buffer );


clear() 方法重设缓冲区,使它可以接受读入的数据。 flip() 方法让缓冲区可以将新读入的数据写入另一个通道。

分享到:
评论
2 楼 wutao8818 2009-02-22  
看的还真仔细,3Q
1 楼 superherosk123 2009-02-21  
:我们首先从 FileInputStream 获取一个 FileInputStream 对象
这里 错了,应该是 获取一个FileChannel对象

相关推荐

    java nio 读文件

    三、NIO读文件的优势 1. 高效:NIO使用缓冲区进行数据传输,减少了系统调用,提高了性能。 2. 非阻塞:在等待数据时,线程可以做其他工作,避免了阻塞I/O可能导致的资源浪费。 3. 多通道:通过选择器,可以同时监控...

    java NIO 写文件

    在这个主题中,我们将深入探讨Java NIO如何用于写文件,特别是在处理大数据文件时如何提高性能。 首先,理解Java NIO的基本概念非常重要。NIO中的“N”代表“非阻塞”,这意味着在进行I/O操作时,程序可以继续执行...

    手写 tomcat nio

    2. **选择器(Selector)**:选择器是NIO的核心组件,它允许我们监控多个通道的事件(如连接就绪、数据可读或可写等)。通过注册SocketChannel到选择器,我们可以使用一个线程来检查所有连接,而不需要为每个连接...

    NIO与零拷贝_javanio_nio和零拷贝_

    - **通道(Channels)**:通道类似于流,但它是双向的,可以读也可以写。常见的通道有FileChannel、SocketChannel、ServerSocketChannel等。 - **缓冲区(Buffers)**:NIO的核心组件,用于存储数据。它们是固定...

    java NIO实例

    然后,服务器会在接收到读事件时读取客户端发送的数据,在接收到写事件时向客户端发送数据。 整个过程中,NIO通过非阻塞I/O避免了线程阻塞,提高了系统资源的利用率,尤其在处理大量并发连接时,其优势更为明显。 ...

    java NIO.zip

    通过注册感兴趣的事件(如读、写或连接就绪)到选择器,当这些事件发生时,选择器会返回一个包含已准备好的通道的`SelectionKey`集合,然后开发者可以逐个处理这些通道,而无需为每个连接创建单独的线程。...

    动态演示nio中的buffer相关操作.zip

    这个压缩包“动态演示nio中的buffer相关操作.zip”显然是为了帮助用户直观地理解NIO Buffer的工作机制,通过动态演示来展示Buffer如何存储、读取和传输数据。 在Java NIO中,Buffer是一个特定类型的数组,用于临时...

    Java NIO英文高清原版

    与BIO中的流不同,通道是双向的,既可以读也可以写。 2. **缓冲区(Buffer)**:在NIO中,数据被存储在缓冲区对象中。缓冲区提供了一种高效的方式管理内存,可以方便地进行读写操作。缓冲区有固定大小,一旦写满,...

    Java NIO系列教程(一) Java NIO 概述

    NIO的核心在于其三大组件:Channels、Buffers和Selectors。本文将详细介绍这三个组件的基础概念及其应用场景。 #### 二、Channels 和 Buffers 在Java NIO中,所有IO操作都是从Channel开始的。Channel类似于传统的...

    NIO学习系列:连网和异步IO

    而在NIO中,系统会通知我们何时有数据可读或写,这样可以显著提高并发性能。 **连网** 在NIO中,我们可以使用SocketChannel和ServerSocketChannel来实现网络连接。ServerSocketChannel用于监听客户端连接,当有新的...

    自己写的Java NIO 同步不阻塞IO操作

    通常,NIO中的SocketChannel用于网络通信,Selector用于监听多个通道的事件,如连接、读就绪、写就绪等,这样可以同时处理多个连接,而不需要为每个连接创建一个新的线程。 在Java中,`java.nio`包提供了NIO相关的...

    java nio 包读取超大数据文件

    NIO在Java 1.4版本引入,并在后续版本中得到了进一步增强和完善。相较于传统的Java IO,NIO具有更高的性能和更丰富的功能,尤其适合处理大文件或高并发场景。 #### 二、Java NIO关键组件 Java NIO的核心组件包括: ...

    NIO 服务器客户端例子

    在这个"NIO 服务器客户端例子"中,`TestServer.java`和`TestClient.java`分别代表服务器端和客户端的实现。 **NIO服务器端(TestServer.java)的关键知识点:** 1. **选择器(Selector)**:服务器通常会创建一个...

    基于nio实现的多文件上传源码

    在Java编程领域,NIO(New IO)是一个重要的特性,它是Java 1.4版本引入的,用于替代标准的IO API。...在理解和应用这个源码时,深入研究NIO的原理和实践,将有助于进一步提升系统的性能和稳定性。

    基于nio的简易聊天室

    选择器是NIO中的多路复用器,它可以同时监控多个通道的事件(如连接请求、数据可读、写操作完成等)。在聊天室服务端,Selector的使用可以使得服务器在一个线程中管理多个客户端连接,避免了为每个连接创建单独线程...

    Java NIO原理和使用

    NIO 有一个主要的类Selector,这个类似一个观察者,只要我们把需要探知的socketchannel告诉Selector,我们接着做别的事情,当有事件发生时,他会通知我们,传回一组SelectionKey,我们读取这些Key,就会获得我们刚刚注册...

    NIO编程实现实例

    NIO(New Input/Output)是Java平台中用于提高I/O效率的一种编程模型,它与传统的BIO(Blocking I/O)模型相比,提供了更高效的数据传输方式。在BIO中,每个连接都需要一个线程来处理,当并发连接数量增大时,会消耗...

Global site tag (gtag.js) - Google Analytics