Java IO体系综述

一、流的概念

  在Java API中,可以从其中读入一个字节序列的对象称作输入流,而可以向其中写入一个字节序列的对象称作输出流。这些字节序列的来源地和目的地可以是文件,而且通常都是文件,但是也可以是网络连接,甚至是内存块。编程语言的I/O类库中使用流这个抽象概念,它代表任何有能力产出数据的数据源对象或者是有能力接收数据的接收端对象。

  Java中I/O操作主要是指使用Java进行输入,输出操作. Java所有的I/O机制都是基于数据流进行输入输出,这些数据流表示了字符或者字节数据的流动序列。Java的I/O流提供了读写数据的标准方法。任何Java中表示数据源的对象都会提供以数据流的方式读写它的数据的方法。

  Java.io是大多数面向数据流的输入/输出类的主要软件包。此外,Java也对块传输提供支持,在核心库 java.nio中采用的便是块IO。

  流IO的好处是简单易用,缺点是效率较低。块IO效率很高,但编程比较复杂。

  Java IO模型 : Java的IO模型设计非常优秀,它使用Decorator模式,按功能划分Stream,您可以动态装配这些Stream,以便获得您需要的功能。例如,您需要一个具有缓冲的文件输入流,则应当组合使用FileInputStream和BufferedInputStream。

  简单的理解:流是数据和数据处理过程的统称。

  流操作关心三部分内容:数据源、目标以及过程。

  这些数据源包括:

  • 字节数组

  • String对象

  • 文件

  • “管道”,工作方式与实际管道相似,即,从一段输入,从另一端输出。

  • 一个由其他种类的流组成的序列,以便我们可以将它们收集合并到一个流内。

  • 其他数据源,如Internet连接等。

  总体结构:

二、流的分类

  • 按流的方向:输入流和输出流

  可以从其中读入一个字节序列的对象称作输入流,而可以向其中写入一个字节序列的对象称作输出流。入和出都是相对于程序本身来说的(不是相当于流本身,因为程序中的“入”,是将流中的数据读取到程序中,对流来说此时是“出”),比如,在程序中使用一个文件保存数据,进行的操作是向流中写入数据保存到文件,此时的流是输出流;从流中读取数据到程序的流称为输入流。

  上面的概念中也反映了该类流的特点:对输入流只能进行读操作,对输出流只能进行写操作。

  • 按数据单位:字节流和字符流

  在电脑磁盘上,所有的数据都是以字节的形式传输和保存,包括图片、视频、文档等数据。一个字节占用8位二进制(8bit),而一个字符根据编码方式的不同,占用的存储空间是不同的。有句话很适合现在:基本的才是万能的。所以字节流能够处理任何类型的数据,而字符流只能处理字符类型的数据。

  在Java中,所有的字节流都以Stream结尾,所有的字符流都含有Reader或Writer

  字节流适合读取音频、图片等二进制文件,字符流适合读取纯文本文件

  • 按功能:节点流和过滤流

  节点流是使用原始的流类进行的操作,而过滤流是在节点流的基础上进行修饰以获得更多的功能,这里使用了装饰器模式。

三、输入流和输出流层次结构

  • 完整架构

  字节流的顶级父类是抽象类InputStream和OutputStream,输入输出流的层次结构如下图:

  Reader和Writer的层次结构如下图:

  Java类库中的I/O类分成输入和输出两部分,可以在JDK的文档里的类层次结构中查看到。通过继承,任何自InputStream或Reader派生而来的类都含有名为read()的基本方法,用于读取单个字节或字节数组。同样,任何自OutputStream或Writer类派生未来的类都含有名为write()的基本方法,用于写单个字节或者字节数组。但是,我们通常不会用到这些方法,他们之所以存在是因为别的类可以使用它们,以便提供更有用的接口。因此,我们很少使用单一的类来创建流对象,而是通过叠合多个对象来提供所期望的功能(这就是装饰器设计模式)。实际上,Java“流”类库让人迷惑的主要原因就在于:创建单一的结果流,却需要创建多个对象。

  FilterInputStream和FilterOutputStream是用来提供装饰器类接口以控制特定输入流额输出流的两个类,他们的名字不是很直观。FilterInputStream和FilterOutputStream分别自I/O类库中的积累InputStream和OutputStream派生而来,这两个类是装饰器的必要条件(以便能为所有正在被修饰的对象提供通用接口)。

  FilterInputStream类能够完成两件完全不同的事情。其中,DataInputStream允许我们读取不同的基本类型数据以及String对象(所有方法都以“read”开头,例如readByte()、readFloat()等等)。搭配相应的DataInputStream,我们就可以通过数据“流”将基本类型的数据从一个地方迁移到另一个地方。

  其他FilterInputStream类则是在内部修改InputStream的行为方式:是否缓冲,是否保留它所读过的行(允许我们查询行数或设置行数),以及是否把单一字符推回输入流等等。最后两个类看起来更像是为了创建一个编译器(它们被添加进来可能是为了对“用Java构建编译器”实验提供支持),因此我们在一般编程中不会用到它们。

  我们几乎每次都要对输入 进行缓冲——不管我们正在连接的是什么I/O设备,所以,I/O类库把无缓冲输入(而不是缓冲输入)作为特殊情况(或只是方法调用)就显得更加合理了。

四、Java IO分类介绍

4.1 字节流

  常用字节流继承结构图: 

4.1.1字节输入流

  InputStream表示字节输入流的所有类的超类,

  FileInputStream 从文件系统中的某个文件中获得输入字节。

  ByteArrayInputStream 包含一个内部缓冲区,该缓冲区包含从流中读取的字节。内部计数器跟踪read 方法要提供的下一个字节。关闭ByteArrayInputStream 无效。此类中的方法在关闭此流后仍可被调用,而不会产生任何IOException

  PipedInputStream管道输入流应该连接到管道输出流;管道输入流提供要写入管道输出流的所有数据字节。通常,数据由某个线程从PipedInputStream 对象读取,并由其他线程将其写入到相应的PipedOutputStream。不建议对这两个对象尝试使用单个线程,因为这样可能死锁线程。管道输入流包含一个缓冲区,可在缓冲区限定的范围内将读操作和写操作分离开。如果向连接管道输出流提供数据字节的线程不再存在,则认为该管道已损坏。

  FilterInputStream 包含其他一些输入流,它将这些流用作其基本数据源,它可以直接传输数据或提供一些额外的功能。

  ObjectInputStream 对以前使用 ObjectOutputStream 写入的基本数据和对象进行反序列化。

  SequenceInputStream 表示其他输入流的逻辑串联。它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。

  BufferedInputStream 为另一个输入流添加一些功能,即缓冲输入以及支持mark 和reset 方法的能力。在创建BufferedInputStream 时,会创建一个内部缓冲区数组。在读取或跳过流中的字节时,可根据需要从包含的输入流再次填充该内部缓冲区,一次填充多个字节。mark 操作记录输入流中的某个点,reset 操作使得在从包含的输入流中获取新字节之前,再次读取自最后一次mark 操作后读取的所有字节。

  DataInputStream数据输入流允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型。应用程序可以使用数据输出流写入稍后由数据输入流读取的数据。

  PushbackInputStream 为另一个输入流添加性能,即“推回 (push back)”或“取消读取 (unread)”一个字节的能力。

4.1.2字节输出流

  OutputStream此抽象类是表示输出字节流的所有类的超类。

  ByteArrayOutputStream此类实现了一个输出流,其中的数据被写入一个 byte 数组。缓冲区会随着数据的不断写入而自动增长。可使用toByteArray()toString() 获取数据。关闭ByteArrayOutputStream 无效。

  FileOutputStream文件输出流是用于将数据写入 File 或FileDescriptor 的输出流。

  FilterOutputStream此类是过滤输出流的所有类的超类。

  ObjectOutputStream 将 Java 对象的基本数据类型和图形写入 OutputStream。

  PipedOutputStream可以将管道输出流连接到管道输入流来创建通信管道。管道输出流是管道的发送端。

  BufferedOutputStream该类实现缓冲的输出流。通过设置这种输出流,应用程序就可以将各个字节写入底层输出流中,而不必针对每次字节写入调用底层系统。

  DataOutputStream数据输出流允许应用程序以适当方式将基本 Java 数据类型写入输出流中。然后,应用程序可以使用数据输入流将数据读入。

4.2 字符流

  常用字符流类继承结构图:

4.2.1字符输入流

  Reader 用于读取字符流的抽象类。

  BufferedReader从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。

  LineNumberReader跟踪行号的缓冲字符输入流。此类定义了方法setLineNumber(int) 和 getLineNumber(),它们可分别用于设置和获取当前行号。

  CharArrayReader此类实现一个可用作字符输入流的字符缓冲区。

  InputStreamReader 是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。

  FileReader用来读取字符文件的便捷类。此类的构造方法假定默认字符编码和默认字节缓冲区大小都是适当的。

  StringReader其源为一个字符串的字符流。

  PipedReader管道传送的字符输入流。

  FilterReader用于读取已过滤的字符流的抽象类。

  PushbackReader允许将字符推回到流的字符流
reader。

4.2.2字符输出流

  Writer写入字符流的抽象类。

  BufferedWriter将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。

  CharArrayWriter此类实现一个可用作Writer 的字符缓冲区。缓冲区会随向流中写入数据而自动增长。可使用 toCharArray() 和 toString() 获取数据。在此类上调用 close() 无效。

  OutputStreamWriter是字符流通向字节流的桥梁:可使用指定的 charset 将要写入流中的字符编码成字节。它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集。

  FileWriter用来写入字符文件的便捷类。

  PipedWriter管道传送的字符输出流。

  PrintWriter向文本输出流打印对象的格式化表示形式。此类实现在 PrintStream 中的所有 print 方法。它不包含用于写入原始字节的方法,对于这些字节,程序应该使用未编码的字节流进行写入。

  StringWriter一个字符流,可以用其回收在字符串缓冲区中的输出来构造字符串。关闭 StringWriter 无效。

  FilterWriter用于写入已过滤的字符流的抽象类。

这里只综述了一下java io大纲,关于java io的详细介绍,大家可关注我后续的博文

参考文章:

  http://blog.csdn.net/u011596455/article/details/69059499

  http://blog.csdn.net/jianghuxiaojin/article/details/52073031

Java IO体系综述的更多相关文章

  1. Java IO体系之RandomAccessFile浅析

    Java IO体系之RandomAccessFile浅析 一.RandomAccessFile综述: 1.1RandomAccessFile简介 RandomAccessFile是java Io体系中 ...

  2. JAVA基础知识之IO——Java IO体系及常用类

    Java IO体系 个人觉得可以用"字节流操作类和字符流操作类组成了Java IO体系"来高度概括Java IO体系. 借用几张网络图片来说明(图片来自 http://blog.c ...

  3. Java IO体系之File类浅析

    Java IO体系之File类浅析 一.File类介绍 位于java.io下的Java File类以抽象的方式代表文件名和目录路径名.该类主要用于文件和目录的创建.文件的查找和文件的删除等.File对 ...

  4. 高效IO之Java IO体系(一)

    更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680 个人觉得可以用“字节流操作类和字符流操作类组成了Java IO体系”来高度概括J ...

  5. JAVA IO 体系

    一.体系结构

  6. Java IO流题库

    一.    填空题 Java IO流可以分为   节点流   和处理流两大类,其中前者处于IO操作的第一线,所有操作必须通过他们进行. 输入流的唯一目的是提供通往数据的通道,程序可以通过这个通道读取数 ...

  7. Java IO的RandomAccessFile的使用(转)

    现有如下的一个需求,向已存在1G数据的txt文本里末尾追加一行文字,内容如下“Lucene是一款非常优秀的全文检索库”.可能大多数朋友会觉得这个需求很easy,说实话,确实easy,然后XXX君开始实 ...

  8. 关于Java IO与NIO知识都在这里

    由于内容比较多,我下面放的一部分是我更新在我的微信公众号上的链接,微信排版比较好看,更加利于阅读.每一篇文章下面我都把文章的主要内容给列出来了,便于大家学习与回顾. Java面试通关手册(Java学习 ...

  9. Java 基础之详解 Java IO

    Java IO基本概念 Java IO:即Java输入/输出系统,区分Java的输入和输出:把自己当成程序, 当你从外边读数据到自己这里就用输入(InputStream/Reader), 向外边写数据 ...

随机推荐

  1. WebGL中深度碰撞方法总结

    z-fighting问题是三维渲染中常见的问题,本文根据实际工作中遇到的一些场景,进行了系统的总结 一个实际工作中的问题 当两个面离得太近就会发生深度碰撞问题,比如: 遇到深度检测问题,最重要的是先搞 ...

  2. Centos7 安装Homestead环境

    问题1, ==> homestead-7: Waiting for machine to boot. This may take a few minutes... homestead-7: SS ...

  3. JAVA 基于TCP协议的一对一,一对多文件传输实现

    最近老师给我们上了多线程和TCP和UDP协议,其中一个要求就是我们用JAVA协议一个基于TCP和UDP这两种协议的一对一文件上传和一对多文件上传. 然后我就开始分析TCP和UDP这两个协议的特点,发现 ...

  4. 前后端分离 之vue-cli 搭建项目mac 系统讲解

    前端项目搭建必备技术 webpack nodejs 搭建 vue-cli 的安装 以上技术自行了解安装 一:创建前端项目 采用vue-cli 脚手架 1:终端执行如下命令 vue init webpa ...

  5. Spring 核心技术(5)

    接上篇:Spring 核心技术(4) version 5.1.8.RELEASE 1.4.5 自动装配协作者 Spring 容器可以自动连接协作 bean 之间的关系.你可以让 Spring 通过检查 ...

  6. 统计学习方法6—logistic回归和最大熵模型

    目录 logistic回归和最大熵模型 1. logistic回归模型 1.1 logistic分布 1.2 二项logistic回归模型 1.3 模型参数估计 2. 最大熵模型 2.1 最大熵原理 ...

  7. Loadrunner参数(摘)

    一.占有率分析 1. 平均事务响应时间 Average Transaction Response Time 优秀:<2s 良好:2-5s 及格:6-10s 不及格:>10s 2. 每秒点击 ...

  8. openGL基本概念

    OpenGL自身是一个巨大的状态机(State Machine):一系列的变量描述OpenGL此刻应当如何运行.OpenGL的状态通常被称为OpenGL上下文(Context).我们通常使用如下途径去 ...

  9. Mobile game forensics

    My friend Carrie'd like to know "Garena 传说对决" violates any mobile risks such as insecure d ...

  10. 1.Go语言copy函数、sort排序、双向链表、list操作和双向循环链表

    1.1.copy函数 通过copy函数可以把一个切片内容复制到另一个切片中 (1)把长切片拷贝到短切片中 package main import "fmt" func main() ...