Java IO流详解(一)——简单介绍
文件在程序中是以流的形式来传输的。所以用Java来传输文件就得使用到Java IO流。
1、流的概念和作用
流:代表任何有能力产出数据的数据源对象或者是有能力接受数据的接收端对象<Thinking in Java>
流的本质:数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。
作用:为数据源和目的地建立一个输送通道
2、Java IO所采用的模型
Java的IO模型设计非常优秀,它使用Decorator(装饰者)模式(这篇博文详细说明了什么是装饰者模式 传送门),按功能划分Stream,您可以动态装配这些Stream,以便获得您需要的功能。
例如,您需要一个具有缓冲的文件输入流,则应当组合使用FileInputStream和BufferedInputStream。
3、IO流的分类
①、根据数据流向不同分为:输入流和输出流。
输出:把程序(内存)中的内容输出到磁盘、光盘等存储设备中
输入:读取外部数据(磁盘、光盘等存储设备的数据)到程序(内存)中

②、根据处理数据类型的不同分为:字节流和字符流。
字节流:可以用于读写二进制文件及任何类型文件。
字符流:可以用于读写文本文件。
字节流和字符流的区别
字符流的由来: Java中字符是采用Unicode标准,一个字符是16位,即一个字符使用两个字节来表示。为此,JAVA中引入了处理字符的流。因为数据编码的不同,从而有了对字符进行高效操作的流对象。本质其实就是基于字节流读取时,去查了指定的码表。
两者的区别:(1字符 = 2字节 、 1字节(byte) = 8位(bit) 、 一个汉字占两个字节长度)
- 读写单位不同:字节流以字节为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。
- 处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。
- 缓存不同:字节流在操作的时候本身是不会用到缓冲区的,是文件本身的直接操作的;而字符流在操作的时候下后是会用到缓冲区的,是通过缓冲区来操作文件。
总结:优先选用字节流。因为硬盘上的所有文件都是以字节的形式进行传输或者保存的,包括图片等内容。字符只是在内存中才会形成的,所以在开发中,字节流使用广泛。除非处理纯文本数据(如TXT文件),才优先考虑使用字符流,除此之外都使用字节流。
③、根据功能的不同分为:节点流和处理流。
节点流:可以从或向一个特定的地方(节点)读写数据。如FileInputStream,FileReader。
处理流:是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写。如BufferedReader。处理流的构造方法总是要带一个其他的流对象做参数。一个流对象经过其他流的多次包装,称为流的链接。
节点流是直接作用在文件上的流,可以理解为一个管道,文件在管道中传输。
处理流是作用在已有的节点流基础上,是包在节点流的外面的管道(可多层),其目的是让管道内的流可以更快的传输。

4、四个基本的抽象流类型,所有的流都继承这四个。
| 输入流 | 输出流 | |
| 字节流 | InputStream | OutputStream |
| 字符流 | Reader | Writer |
下图是Java IO流的整体架构图,后面的博客会详细的讲解这些流使用:

当看到上面这张图的时候会感到很懵逼,因为这么多的类在使用时是选择字节流输入输出还是选择字符流输入输出呢?其实并不难。
- 如果你要将磁盘光盘中的数据读到程序中,那就选择输入流,反之则是输出流。
- 如果你要传输的是音频视频数据,那就肯定是字节流。如果单独是纯文本文件(如TXT),那就字符流。其实所有数据都可以使用字节流,只是效率高低问题。
- 如上面两个都确定了,就可以选出一个合适的节点流,然后再根据你的需求是否需要额外功能(比如是否需要转换流、高效流等)。

5、IO流常用到的五类一接口
Java IO流中所有的接口和类都放在java.io这个包下。其中最重要的就是5个类和一个接口。5个类指的是File、OutputStream、InputStream、Writer、Reader;一个接口指的是Serializable。如掌握了这些IO的核心使用方法,那么就能把Java IO流玩弄于股掌之中,将它放在手中任意盘它

。
它们的详细介绍如下:
①. File(文件特征与管理):File类是对文件系统中文件以及文件夹进行封装的对象,可以通过对象的思想来操作文件和文件夹。 File类保存文件或目录的各种元数据信息,包括文件名、文件长度、最后修改时间、是否可读、获取当前文件的路径名,判断指定文件是否存在、获得当前目录中的文件列表,创建、删除文件和目录等方法。
②. InputStream(二进制格式操作):抽象类,基于字节的输入操作,是所有输入流的父类。定义了所有输入流都具有的共同特征。
③. OutputStream(二进制格式操作):抽象类。基于字节的输出操作。是所有输出流的父类。定义了所有输出流都具有的共同特征。
④. Reader(文件格式操作):抽象类,基于字符的输入操作。
⑤. Writer(文件格式操作):抽象类,基于字符的输出操作。
⑥. RandomAccessFile(随机文件操作):一个独立的类,直接继承至Object.它的功能丰富,可以从文件的任意位置进行存取(输入输出)操作。
⑦. Serializable(序列化操作):是一个空接口,为对象提供标准的序列化与反序列化操作。
6、Java IO流对象介绍
①、字节输入流InputStream

根据上图介绍各个类的作用:
- InputStream:字节输入流基类,是所有的字节输入流的父类,它是一个抽象类。
- FileInputSream:文件输入流。它通常用于对文件进行读取操作。
- FilterInputStream :过滤流。作用是为基础流提供一些额外的功能。装饰者模式中处于装饰者,具体的装饰者都要继承它,所以在该类的子类下都是用来装饰别的流的,也就是处理类。
- BufferedInputStream:缓冲流。对处理流进行装饰,增强,内部会有一个缓存区,用来存放字节,每次都是将缓存区存满然后发送,而不是一个字节或两个字节这样发送。效率更高。
- DataInputStream:数据输入流。它是用来装饰其它输入流,它“允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型”。
- PushbakInputStream:回退输入流。java中读取数据的方式是顺序读取,如果某个数据不需要读取,需要程序处理。PushBackInputStream就可以将某些不需要的数据回退到缓冲中。
- ObjectInputStream:对象输入流。用来提供对“基本数据或对象”的持久存储。通俗点讲,也就是能直接传输对象(反序列化中使用)。
- PipedInputStream:管道字节输入流。它和PipedOutputStream一起使用,能实现多线程间的管道通信。
- SequenceInputStream:合并输入流。依次将多个源合并成一个源。
- StringBufferInputStream:字符相关流。已经过时不多说。
- ByteArrayInputStream:字节数组输入流,该类的功能就是从字节数组(byte[])中进行以字节为单位的读取,也就是将资源文件都以字节的形式存入到该类中的字节数组中去,我们拿也是从这个字节数组中拿。
②、字节输出流OutputStream

根据上图介绍各个类的作用:
- OutputStream:字节输出流基类,是所有的字节输出流的父类,它是一个抽象类。
- FileOutputStream:文件输出流。该类实现了一个输出流,将数据输出到文件。
- FilterOutputStream :过滤流。用来封装其它的输出流,并为它们提供额外的功能(序列化中使用)。它主要包括BufferedOutputStream, DataOutputStream和PrintStream。
- BufferedOutputStream:缓冲输出流。给输出流提供缓冲功能。
- DataOutputStream:是用来装饰其它输出流,将DataOutputStream和DataInputStream输入流配合使用,“允许应用程序以与机器无关方式从底层输入流中读写基本 Java 数据类型”。
- PrintStream:是用来装饰其它输出流。它能为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。
- ObjectOutputStream:对象输出流。该类将实现了序列化的对象序列化后写入指定地方。
- PipedOutputStream:管道字节输出流。它和PipedInputStream一起使用,能实现多线程间的管道通信,是管道的发送端。
- ByteArrayOutputStream:字节数组输出流。该类实现了一个输出流,其数据被写入由byte数组充当的缓冲区,缓冲区会随着数据的不断写入而自动增长。
③、字符输入流Reader

根据上图介绍各个类的作用:
- Reader:是所有的输入字符流的父类,它是一个抽象类。
- CharReader、StringReader 是两种基本的介质流,它们分别将Char 数组、String中读取数据。
- PipedReader 是从与其它线程共用的管道中读取数据。
- BufferedReader是一个装饰器,它和其子类LineNumberReader负责装饰其它Reader对象。
- InputStreamReader:是一个连接字节流和字符流的桥梁,它将字节流转变为字符流。FileReader 可以说是一个达到此功能、常用的工具类,在其源代码中明显使用了将FileInputStream 转变为Reader 的方法。我们可以从这个类中得到一定的技巧。Reader 中各个类的用途和使用方法基本和InputStream 中的类使用一致。后面会有Reader 与InputStream 的对应关系。
- FilterReader 是所有自定义具体装饰流的父类,其子类PushbackReader 对Reader对象进行装饰,会增加一个行号。
④、字符输出流Writer

根据上图介绍各个类的作用:
- Writer:是所有的输出字符流的父类,它是一个抽象类。
- CharArrayWriter、StringWriter 是两种基本的介质流,它们分别向Char 数组、String 中写入数据。PipedWriter 是向与其它线程共用的管道中写入数据,
- BufferedWriter 是一个装饰器为Writer 提供缓冲功能。
- PrintWriter 和PrintStream 极其类似,功能和使用也非常相似。
- OutputStreamWriter:是OutputStream 到Writer 转换的桥梁,它的子类FileWriter 其实就是一个实现此功能的具体类(具体可以研究一SourceCode)。功能和使用和OutputStream 极其类似。
Java IO流详解(一)——简单介绍的更多相关文章
- Java IO流详解(二)——File类
在上一章博客中简单的介绍了Java IO流的一些特征.也就是对文件的输入输出,既然至始至终都离不开文件,所以Java IO流的使用得从File这个类讲起. File类的描述:File类是文件和目录路径 ...
- java IO流详解
流的概念和作用 学习Java IO,不得不提到的就是JavaIO流. 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输 ...
- 《Java基础知识》Java IO流详解
Java IO概念 1. 用于设备之间的数据传输. 2. Java 将操作数据流的功能封装到了IO包中. 3. 数据流流向分:输入流和输出流,操作对象为文件. 4. 流按照操作数据分:字节流(通用)和 ...
- Java IO流详解(六)——转换流
转换流也是一种处理流,它提供了字节流和字符流之间的转换.在Java IO流中提供了两个转换流:InputStreamReader 和 OutputStreamWriter,这两个类都属于字符流.其中I ...
- Java IO流详解(五)——缓冲流
缓冲流也叫高效流,是处理流的一种,即是作用在流上的流.其目的就是加快读取和写入数据的速度. 缓冲流本身并没有IO功能,只是在别的流上加上缓冲效果从而提高了效率.当对文件或其他目标频繁读写或操作效率低, ...
- Java io流详解四
转载地址:http://www.cnblogs.com/rollenholt/archive/2011/09/11/2173787.html 写在前面:本文章基本覆盖了java IO的全部内容,jav ...
- Java io流详解二
原文地址https://www.cnblogs.com/xll1025/p/6418766.html 一.IO流概述 概述: IO流简单来说就是Input和Output流,IO流主要是用来处理设备之间 ...
- Java IO流详解(四)——字符流Reader和Writer
前面一章介绍了字节流的使用,提到了字节流在处理utf-8编码的中文可能会出现乱码的情况(其他编码的中文同样会出现乱码),所以Java针对这一情况提供了字符流. 但是字符流只能处理字符,不能用来处理 . ...
- Java IO流详解(三)——字节流InputStream和OutPutStream
我们都知道在计算机中,无论是文本.图片.音频还是视频,所有的文件都是以二进制(字节)形式存在的,IO流中针对字节的输入输出提供了一系列的流,统称为字节流.字节流是程序中最常用的流.在JDK中,提供了两 ...
随机推荐
- Go初始化结构体数组/切片
package main import "fmt" func main() { var s []student fmt.Printf("%T\n", s) // ...
- [HDU5382]GCD?LCM!
Description HDU5382 会吗?不会! 设\(F(n)=\sum\limits_{i = 1}^{n}\sum\limits_{j=1}^{n}[lcm(i,j)+gcd(i,j)\ge ...
- 【NS-3学习】ns3-模拟基础:关键概念,日志,命令行参数
前言 本篇博客先介绍在仿真过程中会使用到的一些关键概念,然后介绍便于调试仿真脚本的常用技术:日志.命令行参数. 关键概念 节点 在因特网术语中,主机(终端)是指任何一台连接到网络的计算设备.ns-3并 ...
- sqlserver 优化语句小助手
我们在开发的过程中,经常会遇到一些性能差的问题,此刻我的解决思路一般是,首先在浏览器端监控查看是哪一个调用的方法占用的时间比较长如下图,然后会根据方法定位到具体的方法,然后可能是自己写的遗传sql语句 ...
- MySQL-THINKPHP 商城系统二 商品模块的展示
上回已经说到,商品被分为spu商品和sku商品 , ------------------------------------------------------------------------- ...
- Gym-TORCS安装
系统为Ubuntu16.04来安装Gym-TORCS 安装pip: sudo apt-get install python-pip sudo pip install --upgrade pip 安装p ...
- HTML入门归纳--JavaScript
本人一直在从事.net的开发,界面都是采用的WPF,近期花了一个多月进行HTML前端的学习,在这里呢进行学习总结和归纳. 本系列将主要分为4个模块: 控件 样式 布局 JavaScript 根据多年W ...
- Java - 集合 - 定义和分类
Java集合框架主要包括两种类型的容器:Collection和Map 层级结构图:evernote:///view/27699174/s49/d9aaf84e-e218-40a0-89c1-358 ...
- html标签的快捷
https://www.jianshu.com/p/8f330e3571ee 一: <ul> <li><a href=""></a> ...
- Docker - CentOS 7 安装
1. 概述 安装 docker markdown 显示有点问题 代码块里的 后面应该跟一个换行, 但是没有跟 这样会导致部分命令直接执行没有反应 2. 环境 os CentOS7 用户 root 3 ...