授课语音

Java的IO操作

1. 介绍

Java的IO(输入/输出流)是处理数据读写的核心机制。Java中的IO操作主要包括输入流和输出流。根据数据类型的不同,IO可以分为字节流和字符流。

字节流

字节流用于处理所有类型的数据。主要的字节流类有:

  • java.io.InputStream:读取字节数据的抽象类。

    • java.io.FileInputStream:用于从文件中读取字节数据。
    • java.io.ByteArrayInputStream:用于从字节数组中读取数据。
    • java.io.FilterInputStream:过滤输入流的父类。
      • java.io.BufferedInputStream:为输入流添加缓冲功能,减少IO调用次数,提高性能。
      • java.io.DataInputStream:读取原始数据类型。
      • java.io.PushbackInputStream:提供一个单字节的回推缓冲区。
      • java.io.ObjectInputStream:从流中读取对象数据,用于反序列化。
  • java.io.OutputStream:写入字节数据的抽象类。

    • java.io.FileOutputStream:用于向文件中写入字节数据。
    • java.io.ByteArrayOutputStream:用于写入字节数组。
    • java.io.FilterOutputStream:过滤输出流的父类。
      • java.io.BufferedOutputStream:为输出流添加缓冲功能。
      • java.io.DataOutputStream:写入原始数据类型。
      • java.io.PrintStream:提供各种打印数据的功能。
      • java.io.ObjectOutputStream:向流中写入对象数据,用于序列化。

字符流

字符流专门用于处理文本数据。主要的字符流类有:

  • java.io.Reader:用于读取字符数据的抽象类。

    • java.io.FileReader:用于从文件中读取字符。
    • java.io.BufferedReader:为输入流添加缓冲功能。
    • java.io.InputStreamReader:将字节流转换为字符流。
    • java.io.StringReader:从字符串中读取字符。
    • java.io.FilterReader:过滤输入流的父类。
    • java.io.PushbackReader:提供单一字符的回推缓冲区。
  • java.io.Writer:用于写入字符数据的抽象类。

    • java.io.FileWriter:向文件中写入字符。
    • java.io.BufferedWriter:为输出流添加缓冲功能。
    • java.io.OutputStreamWriter:将字符流转换为字节流。
    • java.io.StringWriter:写入字符缓冲区。
    • java.io.FilterWriter:过滤输出流的父类。

文件处理

  • java.io.File:用于处理文件和目录路径。
  • java.io.RandomAccessFile:支持文件的随机访问。

IO性能最佳实践

  • 使用缓冲流减少IO读取次数,提升性能。
  • 优化传输数据格式,例如使用二进制或压缩格式。
  • 监控IO性能瓶颈,定期优化IO操作的代码,避免频繁创建和销毁IO对象,并及时回收资源。

2. 代码案例

import java.io.*;

// 用于对象流示例的类
class Person implements Serializable {
    private static final long serialVersionUID = 1L; // 版本控制
    private String name; // 姓名
    private int age; // 年龄

    public Person(String name, int age) {
        this.name = name; // 构造函数
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{name='" + name + "', age=" + age + '}'; // 重写toString方法
    }
}

public class IoDemo {

    public static void main(String[] args) {
        String filePath = "example.txt"; // 文件路径
        String content = "Hello, Java IO!"; // 写入内容

        // 文件写入和读取
        writeFile(filePath, content);
        String fileContent = readFile(filePath);
        System.out.println("文件内容: " + fileContent);

        // 字节流读写示例
        byteStreamExample(filePath);

        // 字符流读写示例
        charStreamExample(filePath);

        // ByteArray流示例
        byteArrayStreamExample(content);

        // Data流示例
        dataStreamExample(filePath);

        // Object流示例
        objectStreamExample(filePath);

        // Print流示例
        printStreamExample(filePath);

        // File和RandomAccessFile示例
        fileAndRandomAccessFileExample(filePath);

        // StringReader和StringWriter示例
        stringReaderWriterExample(content);
    }

    // 写入文件
    public static void writeFile(String filePath, String content) {
        try (FileOutputStream fos = new FileOutputStream(filePath)) { // 创建文件输出流
            fos.write(content.getBytes()); // 将字符串转换为字节数组并写入
        } catch (IOException e) {
            e.printStackTrace(); // 打印异常信息
        }
    }

    // 读取文件
    public static String readFile(String filePath) {
        StringBuilder content = new StringBuilder(); // 用于存储读取的内容
        try (FileInputStream fis = new FileInputStream(filePath)) { // 创建文件输入流
            int byteRead;
            while ((byteRead = fis.read()) != -1) { // 循环读取字节
                content.append((char) byteRead); // 将字节转换为字符并追加
            }
        } catch (IOException e) {
            e.printStackTrace(); // 打印异常信息
        }
        return content.toString(); // 返回读取的内容
    }

    // 字节流读写示例
    public static void byteStreamExample(String filePath) {
        try (FileInputStream fis = new FileInputStream(filePath);
             FileOutputStream fos = new FileOutputStream("copy_" + filePath)) { // 创建输入输出流

            byte[] buffer = new byte[1024]; // 定义缓冲区
            int bytesRead;
            while ((bytesRead = fis.read(buffer)) != -1) { // 读取字节
                fos.write(buffer, 0, bytesRead); // 将读取的字节写入目标文件
            }
            System.out.println("字节流复制成功!");
        } catch (IOException e) {
            e.printStackTrace(); // 打印异常信息
        }
    }

    // 字符流读写示例
    public static void charStreamExample(String filePath) {
        try (FileReader fr = new FileReader(filePath);
             FileWriter fw = new FileWriter("char_copy_" + filePath)) { // 创建字符输入输出流

            char[] buffer = new char[1024]; // 定义字符缓冲区
            int charsRead;
            while ((charsRead = fr.read(buffer)) != -1) { // 读取字符
                fw.write(buffer, 0, charsRead); // 将读取的字符写入目标文件
            }
            System.out.println("字符流复制成功!");
        } catch (IOException e) {
            e.printStackTrace(); // 打印异常信息
        }
    }

    // ByteArray流示例
    public static void byteArrayStreamExample(String content) {
        try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) { // 创建字节数组输出流
            baos.write(content.getBytes()); // 将内容写入流
            byte[] byteArray = baos.toByteArray(); // 转换为字节数组
            System.out.println("ByteArray 流内容: " + new String(byteArray)); // 输出内容
        } catch (IOException e) {
            e.printStackTrace(); // 打印异常信息
        }
    }

    // Data流示例
    public static void dataStreamExample(String filePath) {
        try (DataOutputStream dos = new DataOutputStream(new FileOutputStream(filePath))) { // 创建数据输出流
            dos.writeInt(123); // 写入整数
            dos.writeDouble(45.67); // 写入浮点数
            dos.writeUTF("Hello DataOutputStream"); // 写入字符串
            System.out.println("Data 流写入成功!");
        } catch (IOException e) {
            e.printStackTrace(); // 打印异常信息
        }

        try (DataInputStream dis = new DataInputStream(new FileInputStream(filePath))) { // 创建数据输入流
            int intValue = dis.readInt(); // 读取整数
            double doubleValue = dis.readDouble(); // 读取浮点数
            String stringValue = dis.readUTF(); // 读取字符串
            System.out.println("Data 流读取成功:");
            System.out.println("整数值: " + intValue);
            System.out.println("浮点值: " + doubleValue);
            System.out.println("字符串值: " + stringValue);
        } catch (IOException e) {
            e.printStackTrace(); // 打印异常信息
        }
    }

    // Object流示例
    public static void objectStreamExample(String filePath) {
        try (ObjectOutputStream o

os = new ObjectOutputStream(new FileOutputStream(filePath))) { // 创建对象输出流
            Person person = new Person("John", 30); // 创建对象
            oos.writeObject(person); // 写入对象
            System.out.println("Object 流写入成功!");
        } catch (IOException e) {
            e.printStackTrace(); // 打印异常信息
        }

        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath))) { // 创建对象输入流
            Person person = (Person) ois.readObject(); // 读取对象并强制转换
            System.out.println("Object 流读取成功:");
            System.out.println(person); // 输出对象信息
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace(); // 打印异常信息
        }
    }

    // Print流示例
    public static void printStreamExample(String filePath) {
        try (PrintWriter pw = new PrintWriter(new FileWriter(filePath))) { // 创建打印输出流
            pw.println("Hello, PrintWriter!"); // 打印字符串
            pw.printf("Number: %d, Floating point: %.2f%n", 123, 456.78); // 格式化输出
            System.out.println("Print 流写入成功!");
        } catch (IOException e) {
            e.printStackTrace(); // 打印异常信息
        }

        try (BufferedReader br = new BufferedReader(new FileReader(filePath))) { // 创建缓冲输入流
            String line;
            System.out.println("Print 流读取内容:");
            while ((line = br.readLine()) != null) { // 逐行读取
                System.out.println(line); // 输出读取的行
            }
        } catch (IOException e) {
            e.printStackTrace(); // 打印异常信息
        }
    }

    // File和RandomAccessFile示例
    public static void fileAndRandomAccessFileExample(String filePath) {
        File file = new File(filePath); // 创建文件对象
        System.out.println("文件路径: " + file.getAbsolutePath()); // 输出文件路径
        System.out.println("文件是否存在: " + file.exists()); // 检查文件是否存在
        System.out.println("文件长度: " + file.length() + " 字节"); // 输出文件长度

        try (RandomAccessFile raf = new RandomAccessFile(file, "rw")) { // 创建随机访问文件流
            raf.seek(raf.length()); // 移动到文件末尾
            raf.writeBytes("Appending some text to the end of the file.\n"); // 追加文本
            System.out.println("RandomAccessFile 追加成功!");

            raf.seek(0); // 移动到文件开头
            System.out.println("RandomAccessFile 读取内容:");
            String line;
            while ((line = raf.readLine()) != null) { // 逐行读取
                System.out.println(line); // 输出读取的行
            }
        } catch (IOException e) {
            e.printStackTrace(); // 打印异常信息
        }
    }

    // StringReader和StringWriter示例
    public static void stringReaderWriterExample(String content) {
        // 使用StringWriter写入数据
        try (StringWriter sw = new StringWriter()) { // 创建字符串写入流
            sw.write(content); // 写入内容
            String result = sw.toString(); // 获取结果
            System.out.println("StringWriter 内容: " + result); // 输出内容
        } catch (IOException e) {
            e.printStackTrace(); // 打印异常信息
        }

        // 使用StringReader读取数据
        try (StringReader sr = new StringReader(content)) { // 创建字符串读取流
            int charRead;
            StringBuilder sb = new StringBuilder(); // 用于存储读取的字符
            while ((charRead = sr.read()) != -1) { // 逐字符读取
                sb.append((char) charRead); // 将字符追加到结果
            }
            System.out.println("StringReader 读取内容: " + sb.toString()); // 输出内容
        } catch (IOException e) {
            e.printStackTrace(); // 打印异常信息
        }
    }
}

这段代码展示了Java IO操作的多种应用场景,包括文件读写、字节流和字符流的操作,以及如何使用数据流、对象流和打印流等。每个示例都有详细的中文注释,帮助理解代码的每一步操作。

去1:1私密咨询

系列课程: