前言
当我们需要在Java程序中读写文件或者处理流数据时,就需要使用Java IO(Input/Output)相关的API。Java IO提供了丰富的类和方法,可以方便地读取和写入数据,处理文件和流,以及进行网络通信。。
Java IO流程
首先操作系统将内存空间分为了用户空间和内核空间两块,这当然容易理解,内核空间的数据更加重要,要控制访问权限,而用户空间可以是用户可以操作的内存空间。我们的Java程序是运行在用户空间里面。但操作系统是运行在内核空间中,而我们的IO都是通过系统调用实现的。所以就出现了IO过程中需要先复制到内核缓冲区然后再复制到用户缓冲区。
以上图中操作步骤为:
1.从磁盘到内核空间的缓冲区(文件系统缓存):当Java程序读取文件时,操作系统内核会将文件从磁盘中读取到内核空间的缓冲区中。
2.从内核空间的缓冲区到用户空间的缓冲区:Java程序会将数据从内核空间的缓冲区复制到用户空间的缓冲区中进行处理(同步调用操作系统方法)。
3.从用户空间的缓冲区到内核空间的缓冲区:当Java程序将数据写入文件时,数据会先被写入到用户空间的缓冲区中(同步调用操作系统方法)。
4.从内核空间的缓冲区到磁盘:操作系统内核会将数据从内核空间的缓冲区复制到磁盘中。
那么问题来了,为什么叫做阻塞型IO呢?到底阻塞在哪里呢?
其实就阻塞在上面的流程1和流程3中,当java执行了系统读取文件的系统调用后(操作系统先要将数据复制到内核缓冲区,这个过程中Java程序是阻塞的。阻塞也是相对Java而言的,操作系统一直在工作。写入文件数据时,如果内核缓冲区已满,Java线程会被阻塞,直到缓冲区有足够的空间为止。所以叫做阻塞型IO。而其他类型的IO都是针对这两个地方阻塞进行优化来实现的。
Java IO主要分类
Java IO主要分为两大类:字节流和字符流。字节流操作的是字节数据,字符流操作的是字符数据。在实际使用中,我们需要根据具体的业务场景来选择合适的IO类和方法。
一、字节流
字节流是Java IO中最基础的一种流,它可以处理任意类型的数据。在Java中,字节流主要包括InputStream和OutputStream两个抽象类,它们的子类提供了不同的读写方式。
InputStream
InputStream是所有字节输入流的抽象父类,它提供了读取字节数据的方法。常用的子类有FileInputStream、ByteArrayInputStream和BufferedInputStream等。
FileInputStream用于读取文件数据,可以读取任何类型的文件。
ByteArrayInputStream用于读取内存中的字节数组。
BufferedInputStream是对其他字节输入流的缓冲处理,可以提高读取性能。
OutputStream
OutputStream是所有字节输出流的抽象父类,它提供了写入字节数据的方法。常用的子类有FileOutputStream、ByteArrayOutputStream和BufferedOutputStream等。
FileOutputStream用于写入文件数据,可以写入任何类型的文件。
ByteArrayOutputStream用于写入内存中的字节数组。
BufferedOutputStream是对其他字节输出流的缓冲处理,可以提高写入性能。
二、字符流
字符流是Java IO中用于读写文本数据的一种流,它可以处理Unicode字符。在Java中,字符流主要包括Reader和Writer两个抽象类,它们的子类提供了不同的读写方式。
Reader
Reader是所有字符输入流的抽象父类,它提供了读取字符数据的方法。常用的子类有FileReader、CharArrayReader和BufferedReader等。
FileReader用于读取文本文件数据,可以读取任何类型的文本文件。
CharArrayReader用于读取内存中的字符数组。
BufferedReader是对其他字符输入流的缓冲处理,可以提高读取性能。
Writer
Writer是所有字符输出流的抽象父类,它提供了写入字符数据的方法。常用的子类有FileWriter、CharArrayWriter和BufferedWriter等。
FileWriter用于写入文本文件数据,可以写入任何类型的文本文件。
CharArrayWriter用于写入内存中的字符数组。
BufferedWriter是对其他字符输出流的缓冲处理,可以提高写入性能。
三、文件操作
文件操作是Java IO中最常用的操作之一,它可以读写文件、创建文件和删除文件等。Java IO提供了File类和相关的方法,可以方便地进行文件操作。
File类是Java IO中用于表示文件和目录的类,它提供了很多便捷的方法,可以方便地进行文件操作。常用的方法有:
mkdir,创建目录。
createNewFile,创建文件。
delete,删除文件或目录。
exists,判断文件或目录是否存在。
getName,获取文件或目录名。
四、流操作
流操作是Java IO中比较高级的一种操作,它可以对数据流进行处理,包括数据的过滤、转换、压缩和加密等。Java IO提供了很多流类和相关的方法,可以方便地进行流操作。
FilterInputStream和FilterOutputStream
FilterInputStream和FilterOutputStream是Java IO中用于数据过滤的类,它们可以对字节流进行过滤处理,比如加密、解密和压缩等。
ByteArrayInputStream和ByteArrayOutputStream
ByteArrayInputStream和ByteArrayOutputStream是Java IO中用于内存流的类,它们可以在内存中读写数据,比如在内存中生成二维码图片