🍧 Peach

蜜桃学代码

IO - 输入/输出流⑴_分类

Java把所有传统的流类型(类或抽象类)都放在 java.io 包中,以实现输入/输出功能。


(一)流分类

  • Java中把不同的输入/输出源(键盘、文件、网络连接等)抽象表述为“流”(stream),通过流的方式允许Java程序使用相同的方式来访问不同的输入/输出源

      %%{
      init: {
        'themeVariables': {
           'fontSize': '13px'
         }
      }
    }%%
    graph LR
    T(["IO流分类"]):::p
    T --> A(["按照(读/写)
    方向分类"]):::p T --> B(["按照(读/写)
    字节数大小分类"]):::b T --> C(["按照流的
    角色分类"]):::g A -.-> |"in(读取)"| a("文件输入流
    字节型文件输入流
    字符型文件输入流
    "):::lp A -.-> |"out(写入)"| a2("文件输出流
    字节型文件输出流
    字符型文件输出流
    "):::lp B -.-> |"1字节"| b("字节型文件流(二进制内容)
    FileInputStream
    FileOUtputStream
    "):::lb B -.-> |"1字符
    (2字节)
    "| b2("字符型文件流(文本内容)
    FileReader
    FileWriter
    "):::lb C -.-> |"直接连接
    到数据源
    "| c("底层节点流(低级流)"):::lg C -.-> |"封装已存
    在的流
    "| c2("上层处理流(高级流)"):::lg classDef p fill:#ddaebd classDef b fill:#aab7d2 classDef g fill:#9ac5bb classDef lp fill:#f4e4e9 classDef lb fill:#d9dfeb classDef lg fill:#ddebe6 classDef info fill:#f6f6f7,color:#737379,stroke-dasharray: 3 3, stroke-width: 2px



(二)流模型

(1)流的基本概念模型

  • 4个抽象基类

      %%{
      init: {
        'themeVariables': {
           'fontSize': '13px'
         }
      }
    }%%
    graph TD
    t(["4个抽象基类"]):::p
    t --> |"输入流"| A("InputStrean(字节输入流)
    Reader(字符输入流)
    "):::lp t --> |"输出流"| B("OutputStream(字节输出流)
    Writer(字符输出流)
    "):::lp A -.-> a("把输入设备抽象成“水管”,
    水管里的每个“水滴”依次排列"):::info B -.-> b("把输出设备抽象成“水管”,
    水管里没有任何水滴"):::info info("Java IO流40多个类都由它们派生"):::info classDef p fill:#ddaebd classDef b fill:#aab7d2 classDef g fill:#9ac5bb classDef lp fill:#f4e4e9 classDef lb fill:#d9dfeb classDef lg fill:#ddebe6 classDef info fill:#f6f6f7,color:#56565b,stroke-dasharray: 3 3, stroke-width: 2px
  • 输入流:

    输入流使用隐式的记录指针来表示当前正准备从哪个“水滴”开始读取,每当程序从InputStream或Reader里取出一个或多个“水滴”后,记录指针自动向后移动。

    input
  • 输出流:

    当执行输出时,程序相当于依次把“水滴”放入到输出流的水管中,输出流同样采用隐式的记录指针来标识当前水滴即将放入的位置,每当程序向OutputStream或Writer里输出一个或多个水滴后,记录指针自动向后移动。

    output

    注:划分输入/输出流时是从程序运行所在内存的角度来考虑的,因此(内存 —> 硬盘)应该是输出流。

(2)处理流模型

  • 节点流和处理流

    使用节点流(低级流)进行输入/输出时,程序直接连接到实际的数据源,和实际的输入/输出节点连接。

    节点流

    处理流(高级流)对已存在的流进行连接或封装,通过封装后的流来实现数据读/写功能。

    处理流
  • 使用处理流来包装节点流:

    程序通过处理流(又称高级流、包装流、过滤流)来执行输入/输出功能,让节点流与底层的I/O设备、文件交互。(处理流可“嫁接”在任何已存在的流的基础之上)

    📌 Java使用处理流来包装节点流是一种典型的装饰器设计模式,通过使用处理流来包装不同的节点流,既可以消除不同节点流的实现差异,也可以提供更方便的方法来完成输入/输出功能。因此处理流也被称为包装流。

(三)抽象基类

(1)InputStream 和 Reader

  • InputStream包含的3个方法:

    方法 说明
    int read() 从输入流中读取单个字节,返回所读取的字节数据(字节数据可直接转换为int类型)。
    int read(byte[] b) 从输入流中读取数据(最多b.length个字节),并将其存储在字节数组b中,返回实际读取的字节数。
    int read(byte[] b, int off, int len) 从输入流中读取数据(最多len个字节),并将其存储在数组b中,放入数组b中时从off位置开始(并不是从数组起点开始),返回实际读取的字节数。
  • reader包含的3个方法:

    方法 说明
    int read() 从输入流中读取单个字符,返回所读取的字符数据(字符数据可直接转换为int类型)。
    int read(char[] cbuf) 从输入流中读取数据(最多cbuf.length个字符),并将其存储在字符数组cbuf中,返回实际读取的字符数。
    int read(char[] cbuf, int off, int len) 从输入流中读取数据(最多len个字符),并将其存在字符数组cbuf中,从off位置开始,返回实际读取的字符数。
  • 模型

    InputStream 和 Reader 都是将输入数据抽象成如图所示的水管:

    read

    使用数组作为 read() 方法的参数时,可理解为使用一个“竹筒”到水管中取水。直到 read(char[] cbuf)read(byte[] b) 方法返回-1,表明到了输入流的结束点。

(2)OutputStream 和 Writer

  • OutputStream包含的3个方法:

    方法 说明
    void write(int c) 将指定的字节/字符c输出到输出流中。
    int write(byte[]/char[] buf) 将字节数组/字符数组中的数据输出到指定输出流中。
    int write(byte[]/char[] buf, int off, int len) 从输入流中读取数据(最多len个字节),并将其存储在数组b中,放入数组b中时从off位置开始(并不是从数组起点开始),返回实际读取的字节数。
  • Writer包含的2个方法:

    Writer可以用字符串来代替字符数组,即以String对象作为参数

    方法 说明
    int write(String str) 将str字符串里包含的字符输出到指定输出流中。
    int write(String str, int off, int len) 将str字符串里从off位置开始,长度为len的字符输出到指定输出流中。



(四)*流体系

(1)分类

分类 字节输入流 字节输出流 字符输入流 字符输出流
抽象类 InputStream OutputStream Reader Writer
转换类 InputStream-
Reader
OutputStream-
Writer
第一类:数据源类
文件 File-
InputStream
File-
OutputStream
FileReader FilerWriter
数组 ByteArray-
InputStream
ByteArray-
OutputStream
CharArray-
Reader
CharArray-
Writer
对象 Object-
InputStream
Object-
OutputStream
字符串 StringBuffer-
InputStream
StringReader StringWriter
第二类:数据流串联类
管道 Pipe-
InputStream
Pipe-
OutputStream
PipeReader PipeWriter
序列 Sequence-
InputStream
第三类:数据流过滤类
过滤 Filter-
InputStream
Filter-
OutputStream
FilterReader FilterWriter
缓冲 Buffered-
InputStream
Buffered-
OutputStream
Buffered-
Reader
Buffered-
Writer
数据 Data-
InputStream
Data-
OutputStream
行号 LineNumber-
InputStream
LineNumber-
Reader
推回 Pushback-
InputStream
Pushback-
Reader
格式化 PrintStream PrintWriter

(2)说明

graph LR
T(["流体系说明"]):::p
T -.- 1("抽象基类
无法直接创建实例,
必须通过子类创建"):::p T -.- 2("数据源类(节点流)
创建各种流的起始类,
必须与指定物理节点关联"):::g T -.- 3("数据流串联类
数据流过滤类

是对各种流实例的包装"):::g T -.- 4("#12288;#12288;#12288;转换类#12288;#12288;#12288;"):::g %% 抽象基类 1 -.- input("InputStream、OutputStream、Reader、Writer …………………………………………………………  FilterInputStream、FilterOutputStream、#12288;#12288; FilterReader、FilterWriter#12288;#12288;#12288;#12288;#12288;#12288;#12288;#12288;#12288; "):::lp %% 数据源类 2-.- array(" 文件流:以文件为数据源,可操作文件中的内容 …………………………………………………………  数组流:将内存中的内部缓存区作为数据源。#12288; …………………………………………………………  对象流:通过字节流读写对象,实现对象序列化 …………………………………………………………  字符串:数据源为字符串的字符流。#12288;#12288;#12288;#12288;#12288; "):::lg %% 流串联类 3 -.- pip(" 管道流:管道(pipe),实现进程间的通信功能。  …………………………………………………………  序列流:表示其他输入流的逻辑串联,可合并流。 "):::lg %% 流过滤类 3 -.- ft(" 过滤流:封装其他流,并为它们提供额外功能。 …………………………………………………………  缓冲流:增加缓冲功能,对流起缓冲装饰。#12288;#12288; …………………………………………………………  数据流:可按8种基本类型和字符串来读写流。  …………………………………………………………  行号流:可跟踪、设置行号,标记以恢复等。#12288; …………………………………………………………  推回流:将内容推回到推回缓冲区以重复读取。 …………………………………………………………  打印流:将基本类型、对象输出为字符串表示。 "):::lg %% 转换类 4 -.- isr("转换流:将字节流转换成字符流#12288;#12288;#12288;#12288;#12288;#12288;#12288;#12288;"):::lg classDef p fill:#e5c0cb classDef b fill:#aab7d2 classDef g fill:#a6ccc3 classDef lp fill:#f4e4e9 classDef lb fill:#d9dfeb classDef lg fill:#ddebe6 classDef info fill:#f6f6f7,color:#737379,stroke-dasharray: 3 3, stroke-width: 2px

(3)子类图

* InputStream

classDiagram
class InputStream
class ByteArrayInputStream
class FileInputStream
class ObjectInputStream
class FilterInputStream
class PipedInputStream
class SequenceInputStream 
class StringBufferInputStream
class BufferedInputStream
class DataInputStream
class LineNumberInputStream
class PushbackInputStream

InputStream <|-- ByteArrayInputStream
InputStream <|-- FileInputStream
InputStream <|-- FilterInputStream
InputStream <|-- ObjectInputStream
InputStream <|-- PipedInputStream
InputStream <|-- SequenceInputStream
InputStream <|-- StringBufferInputStream

FilterInputStream <|-- BufferedInputStream
FilterInputStream <|-- DataInputStream
FilterInputStream <|-- LineNumberInputStream
FilterInputStream <|-- PushbackInputStream

* OutputStream

classDiagram
class OutputStream
class ByteArrayOutputStream
class FileOutputStream
class ObjectOutputStream
class FilterOutputStream
class PipedOutputStream
class BufferedOutputStream
class DataOutputStream
class PrintOutputStream

OutputStream <|-- ByteArrayOutputStream
OutputStream <|-- FileOutputStream
OutputStream <|-- FilterOutputStream
OutputStream <|-- PipedOutputStream
OutputStream <|-- ObjectOutputStream
FilterOutputStream <|-- BufferedOutputStream
FilterOutputStream <|-- DataOutputStream
FilterOutputStream <|-- PrintOutputStream

* Reader:

classDiagram 
class Reader
class CharArrayReader
class StringReader
class PipedReader
class BufferedReader
class FilterReader
class InputStreamReader
class LineNumberReader
class PushbackReader
class FileReader

Reader <|-- CharArrayReader
Reader <|-- BufferedReader
Reader <|-- FilterReader
Reader <|-- StringReader
Reader <|-- PipedReader
Reader <|-- InputStreamReader
InputStreamReader <|-- FileReader
FilterReader <|-- PushbackReader
BufferedReader <|-- LineNumberReader

* Writer

classDiagram 
class Writer
class CharArrayWriter
class StringWriter
class PipedWriter
class PrintWriter
class BufferedWriter
class FilterWriter
class OutputStreamWriter
class FileWriter

Writer <|-- CharArrayWriter
Writer <|-- StringWriter
Writer <|-- PipedWriter
Writer <|-- PrintWriter
Writer <|-- OutputStreamWriter
Writer <|-- BufferedWriter
Writer <|-- FilterWriter

OutputStreamWriter <|-- FileWriter




- end -


🔖 笔记来自:

  1. 《Java编程的逻辑》
  2. 《Java高手真经(编程基础卷)》
  3. 《疯狂Java讲义》