Java NIO 概览外文翻译资料

 2022-08-06 14:13:15

英语原文共 11 页,剩余内容已隐藏,支付完成后下载完整资料


Java NIO 概览

Java NIO包括一下核心组件:

  • Channels
  • Buffers
  • Selectors

Java NIO不止拥有这些类和组件,不过Channel, Buffer 和 Selector组成API的核心部分。其他的组件,例如Pipe和FileLock都是较少使用的工具类,它们一般用来与那三个核心组件合作。因此,在这篇概览中将只关注那三个核心组件。其他组件将在之后进行介绍。

Channels and Buffers

一般来说,所有的NIO中的IO操作都以一个Channel作为开始。Channel有一点像流(stream)。来自Channel中的数组可以被读入Buffer中,数据也可以从Buffer写入到Channel。下面是描述这一过程的插图:

Java NIO: Channel读取数据到Buffer,以及Buffer写入数据到Channel

Java提供了几种Channel和Buffer类型,下面是Java NIO中主要的Channel实现类:

  • FileChannel
  • DatagramChannel
  • SocketChannel
  • ServerSocketChannel

如你所见,这些channels包含了UDP TCP网络IO以及文件IO。

还有一些有趣的接口与这些类合作,但是在这篇概览中我尽量保证简单的目的,所以不介绍它们。它们将会在之后的文章中被介绍。

下面是Java NIO中的核心Buffer实现类:

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

这些Buffer包含了你可以通过IO发送的基本数据类型:byte, short, int, long, float, double以及characters。

Java NIO还提供了一个MappedByteBuffer,它可以被用来和内存映射文件协作。

Selectors

Selector允许一个线程处理多个Channels。如果你的应用拥有很多打开的连接(Channel),但是在每个连接中只有很少的数据传输,它将会让你能够方便处理。例如,一个聊天服务器。

下面是一个线程使用一个Selector来处理三个Channel的插图:

Java NIO: 一个线程使用一个Selector处理三个Channel

为了使用Selector,你需要将Channel注册到它上面。然后,你需要调用它的select()方法,这个方法将会阻塞直到某一个被注册的Channel的事件就绪。一旦这个方法返回,线程就可以处理这些事件。正在到来的连接,数据已被接受等都可以算是事件。

Java NIO 通道

Java NIO Channel(通道)与流很相似,不过有一些不同之处:

  • 你可以同时对Channel进行读取以及写入,而流一般都是单向的(或者读取或者写入)。
  • Channel可以异步读取以及写入。
  • Channel总是读取到Buffer或者从Buffer中写入。

正如之前所提及的,你可以从buffer中写入数据到Channel中,也可以从Channel中读取数据到Buffer。

Java NIO: Channel读取数据到Buffer,以及Buffer写入数据到Channel

Channel实现

下面是Java NIO中最重要的Channel实现类:

  • FileChannel
  • DatagramChannel
  • SocketChannel
  • ServerSocketChannel

FileChannel负责和文件交互,读取或者写入数据到文件。

DatagramChannel可以通过UDP在网络中读取和写入数据。

SocketChannel可以通过TCP在网络中读取和写入数据。

ServerSocketChannel允许你监听将要来到的TCP连接,例如web服务器所做的。对于每一个来临的连接,将会对应创建一个SocketChannel。

基础的Channel示例

下面是使用FileChannel从文件中读取数据到Buffer中的一个例子:

RandomAccessFile aFile = new RandomAccessFile('data/nio-data.txt', 'rw');

FileChannel inChannel = aFile.getChannel();

ByteBuffer buf = ByteBuffer.allocate(48);

int bytesRead = inChannel.read(buf);

while (bytesRead != -1) {

System.out.println('Read ' bytesRead);

buf.flip();

while(buf.hasRemaining()){

System.out.print((char) buf.get());

}

buf.clear();

bytesRead = inChannel.read(buf);

}

aFile.close();

注意buf.flip()这个调用。首先你读取数据到Buffer中,然后你翻转(flip)它,再从中读取数据。在下一节中我将会介绍更多关于Buffer的细节。

Java NIO缓冲区

Java NIO 缓冲区在与NIO Channels交互时使用。正如你所知道的,数据从channel读取到buffer,并且从buffer写入到channel中。

缓冲区本质上是一块内存,你可以写入数据到里面,之后再从其中读取。这个内存块被包装成一个NIO Buffer对象,它提供了一组方法使得你可以更容易与这个内存块工作。

Buffer基础使用

使用Buffer来读取和写入数据一般遵循下面4步:

  1. 写入数据到Buffer
  2. 调用buffer.flip()方法
  3. 从Buffer读取数据
  4. 调用buffer.clear()或者buffer.compact()方法

当你写入数据到缓冲区中时,这个缓冲区将会跟踪你写入了多少数据。一旦你需要读取数据,那么你需要调用flip()方法将缓冲区的状态从写模式切换到读模式。在读模式中,你将可以读取所有之前写入到缓冲区的数据。

一旦你读取了所有数据,你需要清除缓冲区,以使得它可以再次准备写入。你可以通过两种方式完成这个目的:调用clear()或者compact()方法。clear()方法将会清除整个缓冲区,而compact()方法只会清除你已经读取的数据,其他未被读取的数据将会被移动到缓冲区头部,并且现在数据可以在未被读取的数据区域之后写入。

这里有一个简单的Buffer用例,写入,翻转,读取以及清除操作都被包含在其中:

RandomAccessFile aFile = new RandomAccessFile('data/nio-data.txt', 'rw');

FileChannel inChannel = aFile.getChannel();

ByteBuffer buf = ByteBuffer.allocate(48);

int bytesRead = inChannel.read(buf);

while (bytesRead != -1) {

System.out.println('Read ' bytesRead);

buf.flip();

while(buf.hasRemaining()){

System.out.print((char) buf.get());

}

buf.clear();

bytesRead = inChannel.read(buf);

}

aFile.close();

缓冲区Capacity,Position以及Limit

为了理解缓冲区如何工作,你需要熟悉缓冲区的三个属性。它们是:

  • capacity
  • position
  • limit

position以及limit的意义依赖缓冲区处于读模式还是写模式。capacity的含义只有一个,不管处于什么模式。

下面是关于读写两个模式下capacity,position以及limit的插图:

Java NIO: 读写模式下的缓冲区容量以及下标

Capacity

作为一个内存块,缓冲区拥有某个固定的大小,也被称作容量。你只可以将bytes,longs,chars等写入到缓冲区中。一旦缓冲区被填满,在你写入更多数据前,你需要清空它(读取数据或者清除它)。

Position

当你写入数据到缓冲区时,你将在某一个下标进行写入,初始下标为0。当byte,long等被写入到缓冲区中时,缓冲区的下标将会向前推进直到指向下一个可以插入数据的位置。下标的最大值为capacity - 1。

当你从缓冲区读取数据时,也会从一个给定的下标开始读取。当你将缓冲区的写模式翻转到读模式时,下标将会被重置为0。当你从这个下标读取数据时,下标将会向前推进到下一个要被读取的位置。

Limit

在写模式中,缓冲区的limit表示你可以写入多少数据到缓冲区中。在写模式中,limit等同于capacity。

当处于读模式时,limit意味着你可以从缓冲区中读取多少数据。因此,当翻转缓冲区为读模式时,limit被设置为写模式的写下标。换句话说,你可以读取所有你之前写入的数据(limit被设置为写入的字节数量)。

Buffer类型

Java NIO拥有以下缓冲区类型:

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

正如你见到的,这些缓冲区类型表示不同的数据类型。换句话说,它们使得你可以在缓冲区中将字节视为char,short,int,long,float或者double。

MappedByteBuffer则有一些特别,它将在之后被介绍。

分配缓冲区

为了获取一个缓冲区对象,你必须先分配它。每一个缓冲区类都拥有一个allocate()方法做这件事,这里是一个展示分配48字节的缓冲区的例子:

ByteBuffer buf = ByteBuffer.allocate(48);

这里是一个分配1024个字符的缓冲区的例子:

CharBuffer buf = CharBuffer.allocate(1024);

写入数据到缓冲区

你可以通过两种方式写入数据:

  1. 从Channel中写入数据到Buffer
  2. 通过缓冲区的put()方法自己写入数据到缓冲区

下面展示Channel如何写入数据到缓冲区:

int bytesRead = inChannel.read(buf); //read into buffer.

下面展示如何通过put()方法写入数据:

buf.put(127);

有许多其他版本的put()方法,允许你以多种不同的方式写入数据。例如,在指定的位置写入或者写入一个数组的字节,查看JavaDoc获取更多信息。

flip()

flip()方法将缓冲区从写模式切换到读模式,调用flip()方法会将pos

剩余内容已隐藏,支付完成后下载完整资料


资料编号:[254161],资料为PDF文档或Word文档,PDF文档可免费转换为Word

原文和译文剩余内容已隐藏,您需要先支付 30元 才能查看原文和译文全部内容!立即支付

以上是毕业论文外文翻译,课题毕业论文、任务书、文献综述、开题报告、程序设计、图纸设计等资料可联系客服协助查找。