Java I/O
参考链接:https://blog.csdn.net/m0_71563599/article/details/125120982
https://www.cnblogs.com/shamo89/p/9860582.html
https://blog.csdn.net/weixin_48351326/article/details/125017750
整体结构
Java序列化
Java序列化定义: Java序列化是将对象转化为字节流的过程,以便将其存储在磁盘上或通过网络传输。在Java中,对象是在内存中存储的,因此无法在不进行序列化的情况下直接将其存储到磁盘或通过网络传输。序列化将对象转化为字节流,以便可以在磁盘上存储或通过网络传输,并且在需要时可以反序列化为Java对象。这使得Java程序可以在不同的机器和操作系统之间共享数据,并使得持久性存储成为可能。
Java序列化实现: 将被序列化的类实现Serialize接口,然后使用一个输出流来构造一个ObjectOutputStream对象,再使用ObjectOutputStream对象的write(Object obj)方法就可以将obj写出。
字节流
字节流在默认情况下是不支持缓存的,这意味着每调用一次read方法都会请求操作系统来读取一个字节,这往往会伴随着一次磁盘IO,因此效率会比较低。InputStream类中read的以字节数组为参数的重载方法本质上是循环调用read()方法。要使用内存缓冲区以提高读取的效率,应该使用BufferedInputStream。
字符流
字符流处理的基本单位是Unicode码元。通常用来处理文本数据。Java中的String类型默认就把字符以Unicode规则编码后存储在内存中。
输出字符流: 把要写入文件的字符序列(实际上是Unicode码元序列)转为指定编码方式下的字节序列,然后再写入到文件中。
输入字符流: 把要读取的字节序列按指定编码方法解码为相应字符序列(实际上是Unicode码元序列),从而存在内存中。
字符流和字节流的区别
- 字节流操作的基本单位为字节;字符流操作的基本单位为Unicode码元。
- 字节流默认不适用缓冲区;字符流使用缓冲区。
- 字节流是用于处理二进制数据,它通常用来处理任意类型的数据,但它不支持直接写入活读取Unicode码元;字符流通常处理文本数据,它支持写入及读取Unicode码元。
什么时候应该选择字节流,什么时候应该选择字符流?
大多数情况下使用字节流会更好,因为大多时候I/O操作都是直接操作磁盘文件。如果对于操作需要通过I/O在内存中频繁处理字符串的情况下使用字符串会好些,因为字符流会使用缓冲区提高性能。
如果是音频文件、图片、歌曲用字节流比较合适,如果是文本的,用字符流比较合适。
什么是缓冲区?有什么作用?
缓冲区是一段特殊的内存区域,用来缓冲输入或输出的数据。为了提升性能将一部分数据暂时读写到缓冲区,以后直接从此区域中读写数据。
流是怎么关闭的?
流一旦打开就必须关闭,使用close方法,放入finally语句块中,多个处理流互相调用只需要关闭最外层的流。
什么是节点流,什么是处理流,它们各有什么用处,处理流的创建有什么特征?
节点流: 直接与数据源或目的地进行交互,它们提供了一种直接的方式来读取或写入数据。节点流通常与文件、套接字等 I/O资源直接关联。
处理流: 是基于节点流构建的,它们提供了更高层次的数据处理功能。处理流通常与节点流链接起来使用,使得数据在读取或写入时可以经过一系列处理,比如缓冲、压缩、加密等操作,从而提高数据处理的效率和安全性。
处理流的创建有以下特征:
- 处理流必须建立在一个已有的节点流之上。也就是说,处理流无法独立存在,必须与底层的节点流链接在一起使用。
- 处理流通常是装饰器模式的典型应用,因为处理流可以对底层节点流进行功能扩展,而不需要修改节点流的代码。
- 处理流可以按照需要进行堆叠。也就是说,可以将多个处理流链接在一起形成处理流的链条,以便实现更复杂的数据处理操作。
节点流和处理流各有不同的用途:
节点流用于直接与底层数据源或目的地进行交互,适合于处理原始的二进制数据和文本数据。比如FileInputStream和FileOutputStream可以用于读取和写入文件,SocketInputStream和SocketOutputStream可以用于与套接字进行交互。
处理流用于对底层数据进行加工处理,提高处理的效率和安全性。比如BufferedInputStream和BufferedOutputStream可以用于提高读写文件的效率,GZIPInputStream和GZIPOutputStream可以用于压缩和解压缩数据,ObjectInputStream和ObjectOutputStream可以用于序列化和反序列化对象等。
PrintStream、BufferedWriter、PrintWriter的比较?
- 处理方式不同:PrintStream和PrintWriter会自动刷新输出缓冲区,而BufferedWriter需要手动调用flush()方法才能将缓冲区的数据输出到目的地。
- 异常处理方式不同:PrintStream和PrintWriter不会抛出IOException异常,而BufferedWriter发生异常会抛出IOException或UncheckedIOException。
- 性能和效率不同:BufferedWriter在输出大量数据时,由于数据先被缓冲到内存中,因此具有更高的性能和效率。PrintStream和PrintWriter在输出大量数据时,由于数据需要转换成字符,因此可能会导致性能和效率的下降。
- 数据输出方式不同:PrintStream和PrintWriter可以输出任意类型的数据,而BufferedWriter只能输出字符数据。另外,PrintStream和PrintWriter输出的数据是通过字节流转换成字符后输出的,而BufferedWriter输出的数据是直接写入字符缓冲区中的。
综上所述,如果需要输出大量数据,且性能和效率比较重要,可以使用BufferedWriter;如果需要输出任意类型的数据,并且异常处理比较简单,可以使用PrintStream或PrintWriter。另外,如果需要将输出数据转换成字符串并进行操作,可以使用PrintWriter。