Java 的字节与字符输入/输出流的类整理——zyx笔记
Posted 从零开始的智障生活
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 的字节与字符输入/输出流的类整理——zyx笔记相关的知识,希望对你有一定的参考价值。
目录
前言
Java定义了专门负责各种方式的输入输出,这些类都被放在java.io包中。其中,所有输入输出流都是抽象类InputStream(字节输入流)或抽象类Reader(字符输入流)的子类。所有输出流都是抽象类OutputStream(字节输出流)或抽象类Write(字符输出流)的子类
输入流:InputStream/Reader
一、InputStream
InputStream是字节输入流的抽象类,是所有字节输入流的父类。
接下来描述:InputStream类的层次结构
顶层:InputStream:字节输入流的抽象类;
1.1 InputStream实现的接口
-
Closeable:
-
AutoCloseable:
1.2 InputStream直接子类
1.2.1 AudioInputStream
一个音频输入流是一个有指定音频格式和长度的输入流。
1.2.2 ByteArrayInputStream
一个字节数组输入流包含一个内部缓存,包含可能会从流中读取的的字节。通过read方法一个内部计数器持续跟踪下一个被提供的字节。
1.2.3 FileInputStream
文件输入流从一个文件系统的一个文件中获取输入流。哪些文件可用取决于主机环境。FileInputStream用于读取原始字节流,如图像数据。要读取字符流,请考虑使用FileReader。
1.2.4 FilterInputStream
一个过滤流包含一些其他输入流,过滤流使用这些输入流作为它的基本数据源,可能会在这个过程中转换数据或者提供额外的功能。
FilterInputStream直接子类:
- BufferedInputStream:缓冲输入流向另一个输入流添加功能,即缓冲输入并支持标记和重置方法的能力。
- CheckedInputStream:一种输入流,它也维护正在读取的数据的校验和。校验和可用于验证输入数据的完整性。
- CipherInputStream:密码输入流由一个输入流和一个密码组成,因此read()方法返回的数据是从底层输入流读入的,但已由密码进行了额外处理。密码在被密码输入流使用之前必须完全初始化。
- DataInputStream:一个DataInputStream允许【应用程序】以独立于机器的方式从底层输入流中读取基本的Java数据类型。应用程序使用DataOutputStream写入数据,这些数据以后可以由DataInputStream读取。
- DeflaterInputStream:实现一个输入流过滤器,用于以“deflate”压缩格式压缩数据。
- DigestInputStream:一种透明(transparent)的流,使用流经该流的位来更新相关的信息摘要。
- InflaterInputStream:这个类实现了一个流过滤器,用于以“deflate”压缩格式解压缩数据。它还被用作其他解压缩过滤器的基础,如GZIPInputStream。
- LineNumberInputStream:这个类是一个输入流过滤器,它提供了跟踪当前行号的附加功能。
- ProgressMonitorInputStream:监控从某些输入流读取的进度。该ProgressMonitor通常以大致如下形式调用:
InputStream in = new BufferedInputStream( new ProgressMonitorInputStream( parentComponent, “Reading”+filename, new FileInputStream(fileName))); // 这将创建一个进度监视器来监视读取输入流的进度。
- PushbackInputStream:PushbackInputStream 通过将推回的字节存储在内部缓冲区中,加入功能到另一个输入流,即“push back”和“unread”bytes的能力。这在方便片段读取由特定字节限定的无限数量的数据的字节的情况下很有用;读取终止字节后,代码片段可以“未读”它。
1.2.5 ObjectInputStream
ObjectInputStream反序列化原始数据和以前使用ObjectOutputStream编写的对象。
当分别与FileInputStream和FileOutputStream输入流一起使用时,ObjectInputStream和ObjectOutputStream可以为应用程序提供图形对象的持久存储。ObjectInputStream用于恢复那些以前序列化的对象。其他用途包括使用套餐字节流在主机之间传递对象,或者在远程通信系统中封送和取消封送参数和参数。
1.2.6 PipedInputStream
PipedInputStream应该连接到PipedOutputStream。PipedInputStream无论任何字节数据都提供给PipedOutputStream。通常,数据由一个线程从PipedInputStream对象中read,数据是由另一个线程 written to 相应的PipedOutputStream。
不建议从一个线程中同时使用这两个对象,因为这可能会导致线程死锁,PipedInputStream包含一个缓冲区,可以在限制范围内将读操作和写操作分离。
如果向连接的PipedOutputStream提供字节的线程不再活动,则管道被称为断开。
1.2.7 SequenceInputStream
SequenceInputStream表示其他输入流的逻辑串联。它从输入流的有序集合开始,从第一个开始读取,直到到达文件末尾,然后从第二个开始读取,以此类推,直到包含的最后一个输入流到达文件末尾。
1.2.8 StringBufferInputStream
此类允许应用程序创建一个输入流,其中读取的字节由字符串的内容提供。应用程序也可以通过使用ByteArrayInputStream从字节数组中读取字节。
二、Reader
java.io.Reader是字符输入流的抽象类,所有字符输入流的父类。
接下来描述Reader类的层次结构。
2.1 Reader类实现的接口
- Closeable
- AutoCloseable
- Readable
2.2 Reader类的直接子类
2.2.1 BufferedReader
从字符输入流中读取文本,缓冲字符以提供字符、数组、行的有效阅读。
可以指定缓冲区的大小,也可以使用默认大小。对于大多数目来说,默认值足够大。
通常,每个由Reader产生的read请求都会导致底层字符或字节流发出相应的读请求。因此建议在任何read操作代价可能很高的Reader(如FileReader和InputStreamReaders)周围围绕一个BufferedReader。例如:
BufferedReader in = new BufferedReader(new FileReader("foo.in"));
将缓冲来自指定文件的输入。如果没有缓冲,每次调用read()或readLine()都可能导致从文件中读取字节,转换成字符,然后返回,这可能非常低效。
使用DataInputStreams进行文本输入(textual input)的程序可以通过用适当的BufferedReader替换每个DataInputStream来进行本地化。
2.2.2 CharArrayReader
这个类实现了一个能被用作字符输入流的字符缓冲区。
2.2.3 FilterReader
读取字符流的抽象类。子类必须实现的唯一方法是read(char[],int,int)和close。然而大多数子类将覆盖这里定义的一些方法,以便提供更高的效率、额外的功能或两者兼而有之。
FilterReader直接子类
- PushbackReader:一种字符流读取器,允许将字符推回到流中。
2.2.4 InputStreamReader
InputStreamReader是字符流和字节流的一座桥:它将字节用一个指定的字符集解码成字符。它使用字符集的可以是按名字指定、或显式给出,或是接受平台的默认字符集。
每次调用InputStreamReader的read()方法可能会从底层(underlying)字节输入流导致一个或多个字节。为了实现字节到字符的有效转换,可以底层流中提起读取比满足当前读取操作所需的更多字节。可以考虑在InputStreamReader围绕一个BufferedReader:
BufferedReader in = new BufferedReader(new InputStreamReader(System.in))
2.2.5 PipedReader
管道字符输入流。
2.2.6 StringReader
一个字符串的字符流。
输出流OutputStream/Writer
三、OutputStream
java.io.OutputStream是字节输出流的抽象类,所有字节输出流的父类。
接下来描述OutputStream类的层次结构。
3.1 OutputStream类实现的接口
- Closeable
- Flushable
- AutoCloseable
3.2 OutputStream类的直接子类
3.2.1 ByteArrayOutputStream
这个类实现了一个输出流,数据在输出流被写入到一个字节数组。随着写入的数据的增加,缓存自动增加。可以使用toByteArray()和toString()检索数据。
关闭ByteArrayOutputStream没有影响。这个类的方法在ByteArrayOutputStream被关闭后没有依然可以调用,且不会产生IOException。
3.2.2 FileOutputStream
FileOutputStream是一个写入数据到一个文本或一个文件描述器的输出流。能够获取文件或创建文件取决于底层平台。一些平台,特别地,允许一个文件只被一个FileOutputStream(或其他文件写入对象)打开并写入。在这种情形下,如果相关文件已将被打开,则这个类的构造函数将会失败。
3.2.3 FilterOutputStream
这个类是所有的过滤输出流的超类。这些流位于已经存在的输出流(底层输出流)之上,它将该输出流用作基本的数据接收器,但可能会在此过程中转换数据或提供额外的功能。
3.2.4 ObjectOutputStream
ObjectOutputStream将Java对象的原始数据类型和图形写入输出流。可以使用ObjectInputStream读取(重构reconstituted)对象。对象的持久存储可以通过为流使用文件来实现。如果流是网络套接字流,对象可以在另一个主机或另一PipedOutputStream个进程中重新构建。
3.2.5 PipedOutputStream
PipedOutputStream可以连接到管道输入流以创建通信管道。管道输出流是管道的放松端。通常数据由一个线程写入PipedOutputStream对象,而数据由另一个线程从连接的PipedInputStream中读取。不建议从单个线程中同时使用这两个对象,因为这可能会使线程死锁。如果从连接的管道输入流中读取数据字节的线程不再活动,则管道被称为断开。
四、Writer
Writer的层次结构
4.1 Writer实现的接口
4.2 Writer的直接子类
4.2.1 BufferedWriter
将文本写入到一个字符输出流,缓存字符,以便于有效的写入单个字符、数组、字符串。
可以指定缓冲区大小,也可以接受默认大小。对于大多数目的来说,默认值足够大。
提供了一个newLine()方法,该方法使用平台自身的行分隔符概念,如系统属性line.separator。不是所有的平台都是用换行符\\n去结束行。因此调用这个方法去结束每个输出行比直接写入换行符更有效。
通常,一个Writer立即发送它的输出到底层字符到字节流。除非需要提示输出(prompt output is required),否则建议包裹一个BufferWriter在一个write()操作可能代价高昂的Writer的周围,例如FileWriter和OutputStreamWriter。例如:
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("foo.out")));
将会缓存PrintWriter的输出到文件。没有缓存,每次print()方法的调用都会导致字符被转换成字节,这被立刻写入到文件中,这会非常低效。
4.2.2 CharArrayWriter
这个类是实现了一个能被用作一个Writer的字符缓存。当数据写入到这个流中,缓存会立刻增加。通过 toCharArray() 和 toString() 数据能被恢复。
这个类调用close()没有意义,并且在这个流被关闭后这个类的方法依然能被调用,且不产生一个IOException。
4.2.3 FilterWriter
这是一个用于写入字符流的抽象类。抽象类FilterWriter自身提供默认的方法,传输所有的请求到被包含的的流中。
子类应当重写部分方法,并增加功能。
4.2.4 OutputStreamWriter
OutputStreamWriter是将字符流转换成字节流的一个桥梁。被写入到它的字符使用一个特定的字符集被编码成字节。这个字符集可以通过名字指定或被明确给定,或被平台接受的默认字符集。
每次调用write()方法导致编码转换器被指定的字符调用。在被写入到底层输出流之前,这些结果字节被累积在一个缓存中。记住:发送到write()方法的字符不会被缓存。
为了高效,考虑将一个OutputStreamWriter包裹在一个BufferedWriter中,以便于避免频繁地转换调用。例如:
Writer out = new BufferedWriter(new OutputStreamWriter(System.out));
代理对(surrogate pair)是由两个字符值序列表示的字符。范围在'\\uD800'到'\\uDBFF'的高代理,后面紧跟范围在'\\uDC00'到'\\uDFFF'的低代理。
格式不正确(malformed)的代理项元素是后面没有跟着(followed)低代理的高代理或前面(preceded)没有高代理的低代理项。
这个类总是用字符集的默认替代序列代替格式不正确的代理元素和不可映射的字符序列。当更多有请求在编码进程的要求,应当用CharsetEncoder类。
4.2.5 PipedWriter
管道字符输出流。
4.2.6 PrintWriter
将对象的格式化表示打印到文本输出流中。这个类实现了所有PrintStream中的打印方法。它不包括方法用来写入原始字节码,因此程序应当使用未编码的字节流。
不同于PrintStream类,如果启用了自动刷新,它将仅在调用println、printf或format方法之一时进行,而不是在输出换行符时进行。这些方法使用平台自己的行分隔符而不是换行符。
这个类中的方法从来不抛出输入输出异常,尽管它的一些构造函数可能会抛出。客户端可以通过调用checkError()来查询是否发生了任何错误。
此类总是用字符集的默认替换字符串替换格式错误且不可映射的字符序列。当需要对编码过程进行更多控制时,应该使用CharsetEncoder类。
4.2.7 StringWriter
在字符串缓冲区中收集其输出的字符流,然后可以用它来构造字符串。
关闭字符串编写器没有效果。该类中的方法可以在流关闭后调用,而不会生成IOException。
以上是关于Java 的字节与字符输入/输出流的类整理——zyx笔记的主要内容,如果未能解决你的问题,请参考以下文章