什么是IO流?
IO流,即输入/输出流,是一种抽象概念,它代表了数据的无结构化传递。按照流的方式进行输入输出,数据被当成无结构的字节序或字符序列。换句话说,IO流是以流的方式进行数据的输入和输出操作,通过这种方式,我们可以方便地实现数据的读取和写入,如硬盘文件的读写。
Java IO流可以做出以下划分:
- 按照流的方向划分:
- 输入流(Input Stream):用于从数据源(如文件、网络等)读取数据到程序中。
- 输出流(Output Stream):用于将程序中的数据写入到目标地(如文件、网络等)。
- 按照操作单元划分:
- 字节流(Byte Stream):以字节为单位处理数据,包括InputStream和OutputStream两个抽象基类。字节流主要用于处理二进制数据,可以处理任何类型的数据,如纯文本、图片、音频、视频等。
- 字符流(Character Stream):以字符为单位处理数据,包括Reader和Writer两个抽象基类。字符流主要用于处理文本数据。
- 按照流的角色划分:
- 节点流(Node Stream):直接从数据源或目的地读写数据,没有对其他流的连接或封装。
- 处理流(Processing Stream):不直接连接到数据源或目的地,而是连接在已存在的流(节点流或处理流)之上,通过对数据的处理为程序提供更为强大的读写功能。例如,BufferedInputStream和BufferedOutputStream是对字节输入输出流的缓冲增强,而BufferedReader和BufferedWriter则是对字符输入输出流的缓冲增强,它们都能提高读写效率。
下面四个抽象基类派生出了Java IO流的40多个类。这四个抽象基类分别是:
- InputStream:字节输入流的抽象基类。
- OutputStream:字节输出流的抽象基类。
- Reader:字符输入流的抽象基类。
- Writer:字符输出流的抽象基类。
通过这四个基类及其子类,Java提供了丰富而灵活的IO流操作方式,使得我们可以方便地处理各种类型的数据输入和输出任务。无论是文件读写、网络通信还是其他数据操作,Java IO流都发挥着重要的作用。
在Java IO库中,这些类提供了丰富的输入/输出功能,使得文件、网络、内存等不同来源的数据都能被方便地读取和写入。下面将简要说明这些流的使用方法:
字节输入流
- FileInputStream:用于从文件中读取字节数据。
| FileInputStream fis = new FileInputStream("filename.txt"); |
| int data = fis.read(); // 读取一个字节 |
| fis.close(); // 关闭流 |
- BufferedInputStream:提供缓冲功能,以加快读取速度。
| BufferedInputStream bis = new BufferedInputStream(new FileInputStream("filename.txt")); |
| int data = bis.read(); // 读取一个字节 |
| bis.close(); // 关闭流 |
字节输出流
- FileOutputStream:用于将数据写入文件。
| FileOutputStream fos = new FileOutputStream("filename.txt"); |
| fos.write("Hello, World!".getBytes()); // 写入字节数据 |
| fos.close(); // 关闭流 |
- BufferedOutputStream:为输出流提供缓冲功能。
| BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("filename.txt")); |
| bos.write("Hello, World!".getBytes()); // 写入字节数据 |
| bos.close(); // 关闭流 |
字符输入流
| FileReader fr = new FileReader("filename.txt"); |
| char[] buffer = new char[1024]; |
| int length = fr.read(buffer); // 读取字符到缓冲区 |
| fr.close(); // 关闭流 |
- BufferedReader:提供缓冲功能,常用于提高字符流的读取效率。
| BufferedReader br = new BufferedReader(new FileReader("filename.txt")); |
| String line = br.readLine(); // 读取一行文本 |
| br.close(); // 关闭流 |
字符输出流
| FileWriter fw = new FileWriter("filename.txt"); |
| fw.write("Hello, World!"); // 写入字符数据 |
| fw.close(); // 关闭流 |
- BufferedWriter:为输出流提供缓冲功能。
| BufferedWriter bw = new BufferedWriter(new FileWriter("filename.txt")); |
| bw.write("Hello, World!"); // 写入字符数据 |
| bw.close(); // 关闭流 |
特殊用途流
- ObjectInputStream 和 ObjectOutputStream:用于对象的序列化和反序列化。
| // 序列化对象到文件 |
| ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("object.dat")); |
| oos.writeObject(myObject); |
| oos.close(); |
| |
| // 从文件反序列化对象 |
| ObjectInputStream ois = new ObjectInputStream(new FileInputStream("object.dat")); |
| MyObject myObject = (MyObject) ois.readObject(); |
| ois.close(); |
过滤流和转换流
- FilterInputStream 和 FilterOutputStream:用于封装其他输入/输出流,并提供额外的功能。
- InputStreamReader 和 OutputStreamWriter:用于字节流和字符流之间的转换。
在使用这些流时,通常需要遵循以下步骤:
- 创建流对象:根据需求选择合适的流类,并通过构造函数创建流对象。
- 执行读/写操作:使用流对象的读/写方法执行数据读取或写入操作。
- 关闭流:完成读/写操作后,务必调用流的
close()
方法关闭流,释放资源。
请注意,异常处理在实际应用中非常重要。通常,你会在try-catch块中执行这些操作,以捕获并处理可能出现的IOException
。同时,为了资源的有效管理,你还可以考虑使用Java 7引入的try-with-resources语句,它可以确保流在try块执行完毕后自动关闭。