Java.10--IO流
JavaSE(Java Standard Edition)中的IO(输入输出)库提供了用于读写数据的类和接口。
这些功能可以用来处理文件、网络连接、内存中的数据结构等。
一、IO流分类
Java中的IO(输入输出)库可以按照不同的标准进行分类,主要分为以下几种方式:
1.按数据类型分类
字节流(Byte Streams):处理原始的二进制数据。适用于所有类型的文件和数据源。
输入流接口:`InputStream`
输出流接口:`OutputStream`
字符流(Character Streams):专门用于文本数据,能够自动处理字符编码转换。
输入流接口:`Reader`
输出流接口:`Writer`
2.按操作模式分类(按照功能划分)
节点流(Node Streams):直接与特定的数据源或目的地关联,如文件、数组等。
`FileInputStream`, `FileOutputStream`, `FileReader`, `FileWriter`
处理流(Processing Streams):基于其他流之上,提供额外的功能,例如缓冲、过滤、数据格式化等。
缓冲流:`BufferedInputStream`, `BufferedOutputStream`, `BufferedReader`, `BufferedWriter`
数据流:`DataInputStream`, `DataOutputStream`
对象流:`ObjectInputStream`, `ObjectOutputStream`
3.按数据流向分类
输入输出的 方向是针对程序而言,向程序中读入东西,就是输入流,从程序中向外读东西,就是输出流。输入流 是得到数据,输出流是输出数据。
4.按同步性分类
同步I/O:传统的I/O操作是阻塞式的,即当一个线程发起读写请求时,它会一直等待直到操作完成。
异步I/O:非阻塞式操作,允许程序在等待I/O操作完成的同时继续执行其他任务。这通常通过NIO(New IO)包实现,特别是`AsynchronousChannel`类及其子类。
5.按API版本分类(这个来自网络,不是很了解)
旧版I/O(Legacy I/O):包括最初的InputStream/OutputStream和Reader/Writer层次结构。
NIO(New IO):引入了通道(Channel)、缓冲区(Buffer)以及选择器(Selector),支持更高效的I/O操作,尤其是对于网络编程和高并发场景。
NIO.2:进一步增强了文件系统功能,增加了对路径操作的支持、文件属性访问、文件变更通知等功能,并且提供了异步文件通道。
这些分类并不是互斥的,而是从不同角度描述了Java IO库中提供的各种组件和特性。根据具体的应用需求,可以选择最适合的类来实现所需的I/O功能。
二、字节流和字符流
基于字节的流(Byte Stream)和基于字符的流(Character Stream),并且支持同步和异步操作。
字节流(Byte Streams)
字节流适用于所有类型的原始二进制数据,包括图像、音频和其他非文本文件。主要的抽象类是 `InputStream` 和 `OutputStream`,它们分别用于读取和写入字节流。常见的子类有:
1.`FileInputStream` / `FileOutputStream`: 用于文件的读写。
2. `BufferedInputStream` / `BufferedOutputStream`: 提供缓冲功能以提高性能。
3.`DataInputStream` / `DataOutputStream`: 支持基本数据类型的读写。
4. `ObjectInputStream` / `ObjectOutputStream`: 支持序列化对象的读写。
字符流(Character Streams)
字符流专门用于文本数据,自动处理字符编码问题。主要的抽象类是 `Reader` 和 `Writer`,它们提供对字符数据的读写。常见的子类有:
1.`FileReader` / `FileWriter`: 用于文件的字符读写。
2.`BufferedReader` / `BufferedWriter`: 提供缓冲功能,并且支持按行读取/写入。
3. `InputStreamReader` / `OutputStreamWriter`: 桥接字节流和字符流,允许指定字符集。
4.`PrintWriter`: 支持格式化输出。
三、几个问题
1. 输入流和输出流联系和区别,节点流和处理流联系和区别
输入流(Input Stream):
作用:从数据源读取数据。
常见类型:FileInputStream, BufferedReader等。
输出流(Output Stream):
作用:将数据写入目标位置。
常见类型:FileOutputStream, BufferedWriter等。
节点流(Node Stream):
作用:直接与数据源或目的地进行交互。
常见类型:FileInputStream, FileOutputStream, FileReader, FileWriter等。
处理流(Process Stream):
作用:对其他流进行包装,以提供额外的功能(如缓冲、转换等)。
常见类型:BufferedInputStream, BufferedOutputStream, InputStreamReader, OutputStreamWriter等。
2. 字符流字节流联系区别;什么时候使用字节流和字符流?
字符流(Character Stream):
操作对象:字符(char),通常用于处理文本文件。
常用类:Reader, Writer及其子类。
适用场景:文本文件读写,需要考虑字符编码的情况。
字节流(Byte Stream):
操作对象:字节(byte),适用于所有类型的数据。
常用类:InputStream, OutputStream及其子类。
适用场景:图像、音频、视频等二进制文件读写,不需要考虑字符编码的情况。
3. 列举常用字节输入流和输出流并说明其特点,至少5对。
FileInputStream/FileOutputStream:
特点:文件系统中文件的基本读写。
BufferedInputStream/BufferedOutputStream:
特点:提供缓冲功能,提高读写效率。
ByteArrayInputStream/ByteArrayOutputStream:
特点:在内存中操作字节数组,适合小规模数据的操作。
DataInputStream/DataOutputStream:
特点:支持基本数据类型的读写。
PipedInputStream/PipedOutputStream:
特点:进程间通信,通过管道连接两个线程。
4. 说明缓冲流的优点和原理
优点:
减少I/O次数,提高读写效率。
可以一次性读取大量数据,减少等待时间。
原理:
缓冲流内部维护一个缓冲区,当读取数据时,会先将数据读取到缓冲区中,然后从缓冲区中取出数据。写入数据时,会先将数据写入缓冲区,当缓冲区满时,再将数据写入目标位置。
5. 序列化的定义、实现和注意事项
序列化(Serialization):
定义:将对象的状态信息转换为可以存储或传输的形式的过程。
实现:实现Serializable接口,使用ObjectOutputStream.writeObject()方法。
注意事项:
版本控制:serialVersionUID字段用于版本控制。
transient关键字:标记不想被序列化的成员变量。
自定义序列化过程:重写writeObject()和readObject()方法。
6. 使用IO流完成文件夹复制(结合递归)
import java.io.*;
public class FolderCopy {
public static void main(String[] args) {
String sourceFolderPath = "source_folder";
String destinationFolderPath = "destination_folder";
try {
copyFolder(new File(sourceFolderPath), new File(destinationFolderPath));
System.out.println("Folder copied successfully.");
} catch (IOException e) {
e.printStackTrace();
}
}
private static void copyFolder(File sourceFolder, File destinationFolder) throws IOException {
if (!destinationFolder.exists()) {
destinationFolder.mkdir();
}
for (String file : sourceFolder.list()) {
File srcFile = new File(sourceFolder, file);
File destFile = new File(destinationFolder, file);
if (srcFile.isDirectory()) {
copyFolder(srcFile, destFile);
} else {
copyFile(srcFile, destFile);
}
}
}
private static void copyFile(File sourceFile, File destinationFile) throws IOException {
try (InputStream in = new FileInputStream(sourceFile);
OutputStream out = new FileOutputStream(destinationFile)) {
byte[] buffer = new byte[1024];
int length;
while ((length = in.read(buffer)) > 0) {
out.write(buffer, 0, length);
}
}
}
}