I/O流详解

Java基础

浏览数:137

2019-8-23

AD:资源代下载服务

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

作者:司鑫