Java中的IO
Java中的I/OInput/Output输入/输出是程序与外部世界如磁盘文件、网络连接、控制台、内存缓冲区等进行数据交换的机制。其核心是流Stream它代表了一个连续的数据序列数据可以从源头如文件流入程序或从程序流向目的地 。I/O流的主要作用包括读取数据输入和写入数据输出。例如从文件中读取文本内容将用户输入写入到数据库或者通过网络发送和接收数据包。Java I/O流的核心分类Java I/O流体系庞大主要按两个维度进行分类如下表所示分类维度类型说明基类数据单位字节流以字节byte8位为单位进行读写适用于所有类型的文件图片、视频、文本等InputStream/OutputStream字符流以字符char16位Java Unicode为单位进行读写专为文本文件设计能自动处理字符编码Reader/Writer数据流向输入流数据从外部源如文件流入程序InputStream/Reader输出流数据从程序流出到外部目的地如文件OutputStream/Writer常用I/O流及其使用方法Java I/O采用了装饰者模式允许通过组合不同的流来动态添加功能如缓冲、转换数据类型等。以下是几个核心流类的使用示例。1. 文件字节流FileInputStream / FileOutputStream用于读写原始字节数据是最基础的流。import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class FileByteStreamDemo { public static void main(String[] args) { // 写入数据到文件 try (FileOutputStream fos new FileOutputStream(output.dat)) { String data Hello, Java IO!; byte[] bytes data.getBytes(); // 将字符串转换为字节数组 fos.write(bytes); // 写入字节 System.out.println(数据写入成功。); } catch (IOException e) { e.printStackTrace(); } // 从文件读取数据 try (FileInputStream fis new FileInputStream(output.dat)) { byte[] buffer new byte[1024]; int bytesRead fis.read(buffer); // 读取字节到缓冲区 String content new String(buffer, 0, bytesRead); // 将字节数组转换为字符串 System.out.println(读取的内容: content); } catch (IOException e) { e.printStackTrace(); } } }2. 文件字符流FileReader / FileWriter专为文本文件设计简化了字符的读写。import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class FileCharStreamDemo { public static void main(String[] args) { // 写入字符串到文本文件 try (FileWriter fw new FileWriter(demo.txt)) { fw.write(这是一行文本。 ); fw.write(这是另一行文本。); // 对于Writer强烈建议在close前调用flush确保数据完全写出 fw.flush(); System.out.println(文本写入成功。); } catch (IOException e) { e.printStackTrace(); } // 从文本文件读取字符串 try (FileReader fr new FileReader(demo.txt)) { char[] buffer new char[1024]; int charsRead fr.read(buffer); String content new String(buffer, 0, charsRead); System.out.println(读取的文本: content); } catch (IOException e) { e.printStackTrace(); } } }3. 缓冲流BufferedInputStream / BufferedOutputStream / BufferedReader / BufferedWriter通过在内存中建立缓冲区减少对底层设备如磁盘的直接读写次数显著提升I/O效率 。它们是装饰者模式的典型应用。import java.io.*; public class BufferedStreamDemo { public static void main(String[] args) throws IOException { // 使用缓冲字节流复制文件高效 try (BufferedInputStream bis new BufferedInputStream(new FileInputStream(source.jpg)); BufferedOutputStream bos new BufferedOutputStream(new FileOutputStream(copy.jpg))) { byte[] buffer new byte[8192]; // 8KB缓冲区 int len; while ((len bis.read(buffer)) ! -1) { bos.write(buffer, 0, len); } System.out.println(文件复制完成。); } // 使用缓冲字符流按行读取文本文件 try (BufferedReader br new BufferedReader(new FileReader(demo.txt))) { String line; while ((line br.readLine()) ! null) { // 读取一行非常方便 System.out.println(line); } } } }4. 数据流DataOutputStream / DataInputStream用于读写Java基本数据类型如int, double, boolean和String保持数据的原始类型 。import java.io.*; public class DataStreamDemo { public static void main(String[] args) throws IOException { // 写入基本数据类型 try (DataOutputStream dos new DataOutputStream(new FileOutputStream(data.bin))) { dos.writeInt(100); dos.writeDouble(3.14159); dos.writeBoolean(true); dos.writeUTF(Java DataStream); // 写入UTF-8编码的字符串 } // 读取基本数据类型必须按写入顺序和类型读取 try (DataInputStream dis new DataInputStream(new FileInputStream(data.bin))) { int i dis.readInt(); double d dis.readDouble(); boolean b dis.readBoolean(); String s dis.readUTF(); System.out.printf(读取的数据: int%d, double%.5f, boolean%b, string%s%n, i, d, b, s); } } }5. 对象序列化流ObjectOutputStream / ObjectInputStream用于将实现了Serializable接口的Java对象及其状态转换为字节序列序列化进行存储或网络传输并能从字节序列中重建对象反序列化。import java.io.*; class Person implements Serializable { // 必须实现Serializable接口 private String name; private int age; // 构造方法、getter/setter省略... public Person(String name, int age) { this.name name; this.age age; } Override public String toString() { return Person{name name , age age }; } } public class ObjectStreamDemo { public static void main(String[] args) throws IOException, ClassNotFoundException { Person person new Person(张三, 25); // 序列化对象到文件 try (ObjectOutputStream oos new ObjectOutputStream(new FileOutputStream(person.dat))) { oos.writeObject(person); System.out.println(对象已序列化。); } // 从文件反序列化对象 try (ObjectInputStream ois new ObjectInputStream(new FileInputStream(person.dat))) { Person restoredPerson (Person) ois.readObject(); System.out.println(反序列化得到的对象: restoredPerson); } } }关键方法与最佳实践flush()方法对于带有缓冲区的输出流如BufferedOutputStream,BufferedWriter,PrintWriterwrite操作的数据可能暂存于缓冲区。调用flush()会强制将缓冲区中的所有数据立即写入目标设备确保数据不丢失。在关闭流close()前通常建议先调用flush()。close()方法关闭流并释放与之相关的系统资源如文件句柄。必须在finally块或使用try-with-resources语法如上文所有示例来确保流被正确关闭避免资源泄漏。try-with-resources从Java 7开始强烈推荐使用此语法自动管理实现了AutoCloseable接口的资源所有流都实现了该接口。它能确保在语句块结束时每个资源都被自动关闭即使发生异常也是如此。字符编码在字符流与字节流转换时如InputStreamReader/OutputStreamWriter或处理文本时务必注意字符编码如UTF-8, GBK否则会出现乱码。辅助工具Apache Commons IO为了简化繁琐的I/O操作可以使用第三方库如Apache Commons IO。它提供了FileUtils和IOUtils等工具类用一两行代码就能完成文件复制、读写等常见任务 。// 使用commons-io简化文件操作需引入依赖 import org.apache.commons.io.FileUtils; import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; public class CommonsIODemo { public static void main(String[] args) throws IOException { // 将字符串写入文件 FileUtils.writeStringToFile(new File(hello.txt), Hello Commons IO!, StandardCharsets.UTF_8); // 从文件读取字符串 String content FileUtils.readFileToString(new File(hello.txt), StandardCharsets.UTF_8); System.out.println(content); } }综上所述Java I/O是处理数据输入输出的核心API。理解字节流与字符流的区别、掌握装饰者模式下的流组合、熟练使用缓冲流提升性能、了解序列化以及遵循资源关闭和刷新缓冲区的最佳实践是有效进行Java文件和数据操作的关键 。参考来源java--io流二java io 作用_深入理解Java中的IOJava IO流 知识点整理Java学习笔记——IO流深入理解Java中的IOJava IOIO流中的flush方法 .