Java NIO学习教程(一)

原文地址: link.
最近看到一个听不错的Java NIO的学习资料,不过是英文的,翻译谷歌翻译有时又不是很通顺,所以自己照着谷歌的翻译自己理了一遍!

1.Java NIO教程

Java NIO(新IO)是Java的替代IO API(来自Java 1.4),意味着替代标准 Java IO和Java Networking API。Java NIO提供了与标准IO API不同的使用IO的方式。

Java NIO:Channels(通道)and Buffers(缓冲区)
在标准IO API中,你使用字节流和字符流。在NIO中,你使用通道和缓冲区。数据总是从通道读入缓冲区,或从缓冲区写入通道。

Java NIO:Non-blocking IO(非阻塞IO)
Java NIO使你可以执行非阻塞IO。例如,线程可以要求通道将数据读入缓冲区。当通道将数据读入缓冲区时,线程可以执行其他操作。一旦数据被读入缓冲区,线程就可以继续处理它。将数据写入通道也是如此。

Java NIO:Selectors
Java NIO包含“选择器”的概念。选择器是一个可以监视多个事件通道的对象(例如:连接打开,数据到达等)。因此,单个线程可以监视多个通道的数据。

所有这些工作原理将在本系列的下一篇文章 - Java NIO概述中详细解释。

2.Java NIO概述

Java NIO包含以下核心组件:

  • Channels
  • Buffers
  • Selectors

Java NIO有比这些更多的类和组件,但在我看来,ChannelBufferSelector构成了API的核心。其余的组件,如Pipe和FileLock,只是与三个核心组件一起使用的实用程序类。因此,我将在本NIO概述中关注这三个组件。其他组件在本教程其他地方的自己的文本中进行了解释。请参阅本页右上角的菜单。

Channels and Buffers
通常,NIO中的所有IO都以Channel开头。Channel(通道)有点像流。数据可以从Channel中读入Buffer,数据也可以从Buffer中写入Channel。这是一个例子:

图片1

Java NIO:通道将数据读入缓冲区,缓冲区将数据写入通道

有几个ChannelBuffer类型。以下是Java NIOChannel的主要实现类:

  • FileChannel
  • DatagramChannel
  • SocketChannel
  • ServerSocketChannel

如你所见,这些通道涵盖UDP + TCP network IO,和file IO。

这些类也有一些有趣的接口,但为了简单起见,我会将它们排除在Java NIO概述之外。在Java NIO教程的其他文本中,将相关地解释它们。

以下是Java NIOBuffer的核心实现列表:

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

这些Buffer实现涵盖了你可以通过IO发送的基本数据类型:byte,short,int,long,float,double和characters

Java NIO还有一个MappedByteBuffer与内存映射文件一起使用的内容。不过,我会把Buffer这个概括出来。

Selectors
选择器允许单个线程处理多个通道。如果你的应用程序打开了许多连接(通道),但每个连接只有较低的流量,这很方便。例如,在聊天服务器中。

以下是使用Selector处理3个Channel的线程图示:

图片2

要使用选择器,请使用它注册通道。然后你调用它的select()方法。此方法将阻塞,直到其中一个已注册的通道准备好了事件。一旦方法返回,线程就可以处理这些事件。事件的示例是传入连接,接收数据等。

3.Java NIO Channel

Java NIO Channel类似于流,但有一些差异:

  • 你可以读取和写入Channels。流通常是单向的(读或写)。
  • Channels可以异步读取和写入。
  • Channels始终读取缓冲区或从缓冲区写入。

如上所述,你将数据从通道读取到缓冲区,并将数据从缓冲区写入通道。这是一个例子:

图片3

Channel Implementations
以下是Java NIO中最重要的Channel实现:

  • FileChannel
  • DatagramChannel
  • SocketChannel
  • ServerSocketChannel

FileChannel从文件读取数据和向文件写入数据。
DatagramChannel可以通过UDP在网络上读写数据。
SocketChannel可以通过TCP在网络上读写数据。
ServerSocketChannel允许你监听传入的TCP连接,就像Web服务器一样。对于每个传入连接,都会创建一个SocketChannel。

Basic Channel Example
这是一个使用FileChannel将一些数据读入Buffer的基本示例:

public class ExamBuffer {
    public static void main(String[] args) throws IOException {
        RandomAccessFile aFile = new RandomAccessFile("data.txt", "rw");
        FileChannel inChannel = aFile.getChannel();
        // 创建容量为48字节的缓冲区
        ByteBuffer buf = ByteBuffer.allocate(48);

        // 读入缓冲区
        int bytesRead = inChannel.read(buf);
        while (bytesRead != -1) {
            // 使缓冲区做好读取准备
            buf.flip();
            while (buf.hasRemaining()) {
                // 一次读取一个字节
                System.out.print((char) buf.get());
            }
            // 清空缓冲区,使缓冲区准备好写入
            buf.clear();
            bytesRead = inChannel.read(buf);
        }
        aFile.close();
    }
}

注意buf.flip( )调用。首先你读入一个缓冲区。然后你翻转它。然后你读出来了。我将在下一篇关于Buffer的文章中详细介绍。

【下篇】Java NIO学习教程(二)==>点击

  • 5
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值