Java I/O入门

        I/O 或称为输入/输出,指的是计算机与外部世界或者一个程序与计算机的其余部分的之间的接口。它对于任何计算机系统都非常关键,因而所有I/O 的主体实际上是内置在操作系统中的。单独的程序一般是让系统为它们完成大部分的工作。
        在 Java 中,使用"流"的方式完成 I/O操作。所有 I/O 都被视为单个的字节的移动,通过一个称为 Stream 的对象一次移动一个字节,流用于与外部世界接触,它也在内部使用,用于将对象转换为字节,然后再转换回对象。

        所谓流,在计算机中的流其实是一种信息的转换。流是有序的,因此相对于某一对象,通常我们把对象接收外界的信息输入(Input)称为输入流,相应地从对象向外输出(Output)信息为输出流,合称为输入/输出流(I/O Streams)。对象间进行信息或者数据的交换时总是先将对象或数据转换为某种形式的流,再通过流的传输,到达目的对象后再将流转换为对象数据。所以,可以把流看作是一种数据的载体,通过它可以实现数据交换和传输。
        流具有最基本的特点:“One dimension , one direction .” 即流是一维的,同时是单向的。
        所谓一维可以理解为一条线,一维空间中的物体,只有长度,没有宽度和高度。打一个比方,我们要把一个一维的物体(实际上就是一条线段)关起来,只需要在它的两端各加一个点就可以了。
        单向就是必须以一个方向(按顺序从头至尾依次)读写,在读写过程中无法改变方向。

随着JDK1.4开始,引入了NIO的概念,传统I/O只能以流,线性传输的方式得到了扩展,NIO 与原来的 I/O 有同样的作用和目的,但是它使用不同的方式——块,块这种传输方式的效率可以比流 I/O 高许多。

        NIO 的创建目的是为了让 Java 程序员可以实现高速 I/O 而无需编写自定义的本机代码。NIO 将最耗时的 I/O 操作(即填充和提取缓冲区)转移回操作系统,因而可以极大地提高速度。

        原来的 I/O 库(在 java.io包) 与 NIO 最重要的区别是数据打包和传输的方式。正如前面提到的,原来的 I/O 以流的方式处理数据,而 NIO 以块的方式处理数据。
        面向“流”的 I/O 系统一次一个字节地处理数据。一个输入流产生一个字节的数据,一个输出流消费一个字节的数据。为流式数据创建过滤器非常容易。链接几个过滤器,以便每个过滤器只负责单个复杂处理机制的一部分,这样也是相对简单的。不利的一面是,面向流的 I/O 通常相当慢。
        一个 面向“块”的 I/O 系统以块的形式处理数据。每一个操作都在一步中产生或者消费一个数据块。按块处理数据比按(流式的)字节处理数据要快得多。但是面向块的 I/O 缺少一些面向流的 I/O 所具有的优雅性和简单性。

        1.Java流的分类

        1)按流向分:
        输入流: 程序可以从中读取数据的流。
        输出流: 程序能向其中写入数据的流。
        2)按数据传输单位分:
        字节流: 以字节为单位传输数据的流
        字符流: 以字符为单位传输数据的流
        3)按功能分:
        节点流: 用于直接操作目标设备的流
        过滤流: 是对一个已存在的流的链接和封装,通过对数据进行处理为程序提供功能强大、灵活的读写功能。
        4)按阻塞方式分:
        阻塞式:java.io包下常用接口和类
        非阻塞式:java.nio包下常用接口和类

        2.阻塞与非阻塞

        以套接字为例,在阻塞模式下,利用TCP协议发送一个报文时,如果低层协议没有可用空间来存放用户数据,则应用进程将阻塞等待直到协议有可用的空间。而在非阻塞模式下,调用将直接返回而不需等待。在应用进程调用接收函数接收报文时,如果是在阻塞模式下,若没有到达的数据,则调用将一直阻塞直到有数据到达或出错;而在非阻塞模式下,将直接返回而不需等待。对于UDP协议而言,由于UDP没有发送缓存,因此所有UDP协议即使在阻塞模式下也不会发生阻塞。对于面向连接的协议,在连接建立阶段,阻塞与非阻塞也表现不一。在阻塞模式下,如果没有连接请求到达,则等待连接调用将阻塞直到有连接请求到达;但在非阻塞模式下,如果没有连接请求到达,等待连接调用将直接返回。

扫描二维码关注公众号,回复: 834347 查看本文章

        在Java中阻塞式IO在被调用时,会为调用者启动一个单独的线程或者资源去处理调用者的请求,直至本次请求处理完毕之后才会释放此部分被占用的资源。而非阻塞式IO在被调用时,首先会响应调用者的请求,此时用户不必继续等待处理结束,然后根据请求的不同进行分发处理给不同的Channel,再往下处理(更详细流程在nio篇会介绍),等待该请求处理完成后返回给用户,这样nio更像一个io池,即使用户的请求较多也可以一一响应并处理,而不是每一个请求都占有一定的资源。


        3.java.io包结构

        java.io包下结构及相关类如图所示:



 

        4.java.nio包结构

        java.nio包下结构及相关类如图所示:



 

        阅读完本文,对于Java I/O有了一个初步的认识,在接下来的几篇文章中会更加深入的去学习和探讨相关的知识内容
 

猜你喜欢

转载自286.iteye.com/blog/2210879