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

2019-03-15 16:10|来源: 网络

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

  • Channels

  • Buffers

  • Selectors

虽然Java NIO 中除此之外还有很多类和组件,但在我看来,Channel,Buffer 和 Selector 构成了核心的API。其它组件,如Pipe和FileLock,只不过是与三个核心组件共同使用的工具类。因此,在概述中我将集中在这三个组件上。其它组件会在单独的章节中讲到。

Channel 和 Buffer

基本上,所有的 IO 在NIO 中都从一个Channel 开始。Channel 有点象流。 数据可以从Channel读到Buffer中,也可以从Buffer 写到Channel中。这里有个图示:

Channel和Buffer有好几种类型。下面是JAVA NIO中的一些主要Channel的实现:

  • FileChannel

  • DatagramChannel

  • SocketChannel

  • ServerSocketChannel

正如你所看到的,这些通道涵盖了UDP 和 TCP 网络IO,以及文件IO。

与这些类一起的有一些有趣的接口,但为简单起见,我尽量在概述中不提到它们。本教程其它章节与它们相关的地方我会进行解释。

以下是Java NIO里关键的Buffer实现:

  • ByteBuffer

  • CharBuffer

  • DoubleBuffer

  • FloatBuffer

  • IntBuffer

  • LongBuffer

  • ShortBuffer

这些Buffer覆盖了你能通过IO发送的基本数据类型:byte, short, int, long, float, double 和 char。

Java NIO 还有个 Mappedyteuffer,用于表示内存映射文件, 我也不打算在概述中说明。

Selector

Selector允许单线程处理多个 Channel。如果你的应用打开了多个连接(通道),但每个连接的流量都很低,使用Selector就会很方便。例如,在一个聊天服务器中。

这是在一个单线程中使用一个Selector处理3个Channel的图示:

要使用Selector,得向Selector注册Channel,然后调用它的select()方法。这个方法会一直阻塞到某个注册的通道有事件就绪。一旦这个方法返回,线程就可以处理这些事件,事件的例子有如新连接进来,数据接收等。

本文链接:Java NIO系列教程(一) Java NIO 概述,转自:http://ifeve.com/overview/

相关问答

更多
  • OIO是读写阻塞, NIO是读写非阻塞,就是说服务器等待客户端连接这块都是阻塞的, 一旦建立连接了, OIO下, 我读取客户端发来的信息会因网络延时问题又一次阻塞, 你发消息时也是一样 而NIO下, 你的selector.select()如果注册了read或者write, 当消息到达服务端时, 人家从阻塞中醒来提醒你,换句话说, 不是说阻塞消失了, 而是你想多处阻塞等待还是一处阻塞, 然后你干别的事, 数据来了通知你. 如果有兴趣你还可以了解下AIO, 一样有阻塞, 不过很多事操作系统帮你归口做了而已, 与 ...
  • 1,nio的主要作用就是用来解决速度差异的。举个例子:计算机处理的速度,和用户按键盘的速度,这两者的速度相差悬殊。 2,如果按照经典的方法:一个用户设定一个线程,专门等待用户的输入,无形中就造成了严重的资源浪费,每一个线程都需要珍贵的cpu时间片,由于速度差异造成了在这个交互线程中的cpu都用来等待。 3,传统的阻塞式IO,每个连接必须要开一个线程来处理,并且没处理完线程不能退出。 4,非阻塞式IO,由于基于反应器模式,用于事件多路分离和分派的体系结构模式,所以可以利用线程池来处理。事件来了就处理,处理完了 ...
  • NIO只代表New IO。 它是一个增强的通用Java IO软件包,它对异步IO有很多支持,但也包含其他一些增强功能,如支持通过文件名进行查询。 当您尝试执行java.io中的类不支持的操作时,您会使用它。 JMS是一个Java消息传递系统。 当需要让两个应用程序通过类似队列的系统相互通信时,可以使用它。 在底层使用NIO是否是一个实现细节,尽管用Java编写的各种JMS提供者可能会这样做。 NIO just stands for New IO. It's an enhanced general Java ...
  • 那些java.nio.file方法具有可变参数签名 。 看起来Matlab无法进行自动装箱以使它们透明地工作,因此您需要使用其参数的数组形式来调用它们。 java.nio.file.Paths.get的签名是get(String first, String... more) 。 这相当于get(String first, String[] more) 。 >> java.nio.file.Paths.get('C:\', javaArray('java.lang.String', 0)) ans = C:\ ...
  • 有两件事可能会让你的NIO方法变得更好: 尝试使用内存映射文件,而不是将数据读入堆内存。 使用ByteBuffer而不是byte[]数组将数据传递给摘要。 第一个应该避免在文件缓存和应用程序堆之间复制数据,而第二个应该避免在缓冲区和字节数组之间复制数据。 如果没有这些优化,您可能会有更多复制,这是一种天真的非NIO方法。 Two things which would probably make your NIO approach better: Try using a memory-mapped file ...
  • 我希望您的Eclipse项目配置为针对较旧的Java配置文件进行构建。 如果您使用的是Maven,则需要在POM文件中设置所需的Java版本。 否则, 本答案提供了设置项目目标Java版本的说明。 我正在尝试使用命令提示符编译,但仍然得到相同的错误! 在这种情况下,要么使用旧版JDK中的javac进行编译(请参阅javac -version告诉您的内容!!)或者它是POM文件问题。 I expect that your Eclipse project is configured to build again ...
  • 您可以将对象写入ByteArrayOutputStream,从而允许您在发送对象之前给出长度。 在接收方,在尝试解码之前读取所需的数据量。 但是,您可能会发现使用Object * Stream阻塞IO(而不是NIO)更简单,更有效 编辑这样的东西 public static void send(SocketChannel socket, Serializable serializable) throws IOException { ByteArrayOutputStream baos = new ...
  • NIO.2使用IOCP 下面的调用树通过在几个被调用的类名中使用“Iocp”来演示文件i / o,它来自测试平台上的Java 7:NIO.2文件通道 。 另请参见sun.nio.ch.Iocp.java ,“封装I / O完成端口的AsynchronousChannelGroup Windows实现”。 NIO不使用IOCP,因为它只支持“非阻塞i / o”(选择器),而不支持仅与NIO.2一起添加的“异步i / o”(完成处理程序)。 NIO.2 uses IOCP The call tree below ...
  • 就文件复制而言,无论您使用什么平台或API,都不应存在显着差异。 瓶颈是磁盘旋转和头部寻求硬盘驱动器。 * 需要发生的是将硬盘内容移动到某个内存,然后将内存写入硬盘。 使用传统的java io流,会有额外的内存副本。 与磁盘速度相比,这仍然不是很大的浪费。 这可以很容易地验证,FileChannel.transferTo / From无法击败输入输出流复制的旧方式。 (*)当然,现在有更快的磁盘,但只要我们将磁盘定义为内存之后的下一个较慢的存储,该参数就成立了。 (**)我们可以将虚拟磁盘称为磁盘,它实际上 ...
  • Path path = selectedFile.toPath(); Path path = selectedFile.toPath();