I/O流详解

1 I/O流的分类


  • 按照流:

    • 输入流


      输出流
    • 输出流
输入流
  • 按照数据处理单位不同

  • 字节流
    一次读入或者是读取八位二进制,后缀为Stream

  • 字符流
    一次读取或是读取十六位二进制,后缀为Reader、Writer

  • 按照实现功能的不同

  • 节点流


    节点流

    当直接使用节点流时,读写不方便,为了提高效率,才有了处理流。

  • 处理流


    处理流

    处理流是和节点流一起使用,在节点流的基础上套一层,套在节点流上的就是处理流。

2 常见的I/O流


先上图:

几个常见的I/O流

3 字节流


InputStreamOutputStream是两个abstract类,对于字节为导向的 stream 都扩展这两个基类;
3.1 InputStream抽象类

  • 常用的几个方法

  • available():返回stream中的可读字节数,inputstream类中的这个方法始终返回的是0,这个方法需要子类去实现。

  • close():关闭stream方法,这个是每次在用完流之后必须调用的方法。

  • read():方法是读取一个byte字节,但是返回的是int。

  • read(byte[]):一次性读取内容到缓冲字节数组

  • read(byte[],int,int):从数据流中的哪个位置offset开始读长度为len的内容到缓冲字节数组

  • skip(long):从stream中跳过long类型参数个位置

  • mark(int):用于标记stream的作用

  • markSupported():返回的是boolean类型,因为不是所有的stream都可以调用mark方法的,这个方法就是用来判断stream是否可以调用mark方法和 reset方法

  • reset():这个方法和mark方法一起使用的,让stream回到mark的位置。


  • ByteArrayInputStream类:把内存中的一个缓冲区作为InputStream使用

    • 构造器:
      ByteArrayInputStream(byte[]):创建一个新字节数组输入流,从指定的字节数组中读取数据。(使用byte作为缓冲区数组)
      ByteArrayInputStream(byte[],int,int):创建一个新字节数组输入流,从指定的字节数组指定范围读取数据。
  • StringBufferInputSteam类:把一个字符串作为InputStream

  • 构造器:
    StringBufferInputStream(String )
    不建议使用该类,因为该类不能将字符正确的转换成字节。

  • FileInputStream类:将一个文件作为InputStream,对文件进行操作

  • 构造器:
    FileInputStream(File):创建一个文件流,从一个文件中进行读取数据
    FileInputStream(FileDescriptor):创建一个文件流,从指定的文件描述中读取数据
    FileInputStream(String):创建一个输入文件流,从指定的文件名称中读取数据。

  • PipeInputStream类:实现了pipe的概念,在线程中使用,管道输入流是只一个通讯管道的接收端。

  • 构造器:
    PipeInputStream():创建一个管道输入流,它还未和一个管道输出流连接。
    PipeInputStream(PipeOutStream):创建一个管道输入流,已经和管道输出流连接。

  • 方法:
    除了实现InputStream中的部分方法外,还有一个额外的方法
    connection(PipeOutStream):和一个管道输出流连接

  • SequenceInputStream类:把多个InputStream流合并成一个InputStream(序列化流),序列化流允许把几个单独的输入流合并到一起,并让他们像单个输入流一样按顺序输入,当前一个输入流完成后序列化流将自动关闭该流并切换到下一个输入流。

  • 构造器:
    SequenceInputStream(Enumeration)创建一个新的序列化流,并使用一个输入流的枚举初始化它。
    SequenceInputStream(InputStream,InputStream,InputStream...)

  • FilterInputStream:一个过滤的InputStream
    两个常用的子类

  1. BufferedInputStream:使用缓冲区的InputStream
  • 构造器:
    BufferedInputStream (InputStream):用InputStream作为参数初始化实例。
    BufferedInputStream (InputStream,int):设置缓冲区大小的实例。
  1. DataInputStream:数字格式化的stream
  • 构造器
    DataInputStream(InputStream):使用InputStream参数来初始化实例
  • 额外的方法:
    readInt,readFloat,readDouble...这样可以直接从stream中读取基本类型的数据

3.2 OutPutStream抽象类

  • 常用的几个方法

  • write(int):写入一个字节到stream中

  • write(byte[])写入一个byte数组到stream中

  • write(byte[],int,int):把byte数组中从offset开始处写入长度为len的数据

  • close():关闭流,这个是在操作完stream之后必须要调用的方法

  • flush():这个方法是用来刷新stream中的数据,让缓冲区中的数据强制的输出


  • ByteArrayOutputStream: 把信息存入内存中的一个缓冲区中 . 该类实现一个以字节数组形式写入数据的输出流,当数据写入缓冲区时,它自动扩大。用 toByteArray() 和 toString() 能检索数据。

  • 构造器
    ByteArrayOutputStream()创建一个新的字节数组输出流。
    ByteArrayOutputStream(int)创建一个新的字节数组输出流,并带有指定大小字节的缓冲区容量。

  • 额外的方法:
    toByteArray()将字节流转化成一个字节数组,用于数据的检索
    toString()将字节流转化成一个String对象,默认采用系统的编码转化,同样可以用于数据的检索
    toString(String) 根据指定字符编码将缓冲区内容转换为字符串,并将字节转换为字符。
    writeTo(OutputStream)out.write(buf, 0, count)调用输出流的写方法将该字节数组输出流的全部内容写入指定的输出流参数。

  • FileOutputStream: 文件输出流是向 File 或 FileDescriptor 输出数据的一个输出流。

  • 构造器
    FileOutputStream(File name)创建一个文件输出流,向指定的 File 对象输出数据。
    FileOutputStream(FileDescriptor)创建一个文件输出流,向指定的文件描述器输出数据。
    FileOutputStream(String name)创建一个文件输出流,向指定名称的文件输出数据。
    FileOutputStream(String, boolean) 用指定系统的文件名,创建一个输出文件。

  • PipedOutputStream: 管道输出流是指一个通讯管道的发送端。 一个线程通过管道输出流发送数据,而另一个线程通过管道输入流读取数据,这样可实现两个线程间的通讯。

  • 构造器
    PipedOutputStream()创建一个管道输出流,它还未与一个管道输入流连接。
    PipedOutputStream(PipedInputStream)创建一个管道输出流,它已连接到一个管道输入流。

  • 额外的方法:
    connection(PipedInputStream):连接一个PipedInputStream方法

4 字符流


Unicode字符为导向的流,表示以Unicode字符为单位向Stream中存储或者是从Stream中读取。Reader/Writer为抽象类,其中方法和InputStream和OutputStraem中对应。

4.1 Reader

  • CharArrayReader :与 ByteArrayInputStream 对应此类实现一个可用作字符输入流的字符缓冲区

  • 构造器
    CharArrayReader(char[]) 用指定字符数组创建一个 CharArrayReader 。
    CharArrayReader(char[], int, int) 用指定字符数组创建一个 CharArrayReader

  • StringReader: 与 StringBufferInputStream 对应其源为一个字符串的字符流。

  • FileReader **: 与 FileInputStream 对应

  • PipedReader **:与 PipedInputStream 对应

  • InputStreamReader**:将InputStream转化成Reader

4.2 Writer

  • CharArrayWriter: 与 ByteArrayOutputStream对应

  • StringWriter:无与之对应的以字节为导向的stream

  • FileWriter: 与FileOutputStream 对应

  • PipedWriter:与 PipedOutputStream对应

  • OutputStreamWriter:将OutputStream转化成Writer

  • PrintReader:和PrintStream对应

5 两种不同流之间的转换


  • InputStreamReader 类是从字节流到字符流的桥梁:它读入字节,并根据指定的编码方式,将之转换为字符流。
    使用的编码方式可能由名称指定,或平台可接受的缺省编码方式。
  • InputStreamReader 的 read() 方法之一的每次调用,可能促使从基本字节输入流中读取一个或多个字节。
    **为了达到更高效率,考虑用 BufferedReader 封装 InputStreamReader **

6 Java IO 的一般使用原则


  • 按数据来源(去向)分类:
    1 是文件: FileInputStream, FileOutputStream, ( 字节流 )FileReader, FileWriter( 字符 )
    2.是 byte[] : ByteArrayInputStream, ByteArrayOutputStream( 字节流 )
    3 是 Char[]: CharArrayReader, CharArrayWriter( 字符流 )
    4 是 String: StringBufferInputStream, StringBufferOuputStream ( 字节流 )StringReader, StringWriter( 字符流 )
    5 网络数据流: InputStream, OutputStream,( 字节流 ) Reader, Writer( 字符流 )

  • 按是否格式化输出分:
    1 要格式化输出: PrintStream, PrintWriter

  • 按是否要缓冲分:
    1 要缓冲: BufferedInputStream, BufferedOutputStream,( 字节流 ) BufferedReader, BufferedWriter( 字符流 )

  • 按数据格式分:
    1 二进制格式(只要不能确定是纯文本的) : InputStream, OutputStream 及其所有带 Stream 结束的子类
    2 纯文本格式(含纯英文与汉字或其他编码方式); Reader, Writer 及其所有带 Reader, Writer 的子类

  • 按输入输出分:
    1 输入: Reader, InputStream 类型的子类
    2 输出: Writer, OutputStream 类型的子类

  • 特殊需要:
    1 从 Stream 到 Reader,Writer 的转换类: InputStreamReader, OutputStreamWriter
    2 对象输入输出: ObjectInputStream, ObjectOutputStream
    3 进程间通信: PipeInputStream, PipeOutputStream, PipeReader, PipeWriter
    4 合并输入: SequenceInputStream
    5 更特殊的需要: PushbackInputStream, PushbackReader, LineNumberInputStream, LineNumberReader

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容

  • 一、流的概念和作用。 流是一种有顺序的,有起点和终点的字节集合,是对数据传输的总成或抽象。即数据在两设备之间的传输...
    布鲁斯不吐丝阅读 10,003评论 2 95
  • Java 流在处理上分为字符流和字节流。字符流处理的单元为 2 个字节的 Unicode 字符,分别操作字符、字符...
    布鲁斯不吐丝阅读 689评论 0 4
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,490评论 18 139
  • tags:io categories:总结 date: 2017-03-28 22:49:50 不仅仅在JAVA领...
    行径行阅读 2,161评论 0 3
  • 这几天,有老同学问我:是不是写字会上瘾,现在一有时间就想做这件事?我想了一下,好像还真是,不过现在还多了一点:微信...
    郭小果子阅读 367评论 0 1