Skip to content

IO流

IO流体系

字节流
├── InputStream(输入流基类)
│   ├── FileInputStream
│   ├── BufferedInputStream
│   ├── ByteArrayInputStream
│   └── ObjectInputStream
└── OutputStream(输出流基类)
    ├── FileOutputStream
    ├── BufferedOutputStream
    ├── ByteArrayOutputStream
    └── ObjectOutputStream

字符流
├── Reader(输入流基类)
│   ├── FileReader
│   ├── BufferedReader
│   ├── InputStreamReader
│   └── StringReader
└── Writer(输出流基类)
    ├── FileWriter
    ├── BufferedWriter
    ├── OutputStreamWriter
    └── StringWriter

字节流

FileInputStream / FileOutputStream

java
import java.io.*;

public class FileStreamDemo {
    public static void main(String[] args) {
        // 写入文件
        try (FileOutputStream fos = new FileOutputStream("test.txt")) {
            String content = "Hello, Java IO!";
            fos.write(content.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }
        
        // 读取文件
        try (FileInputStream fis = new FileInputStream("test.txt")) {
            int data;
            while ((data = fis.read()) != -1) {
                System.out.print((char) data);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        
        // 批量读取
        try (FileInputStream fis = new FileInputStream("test.txt")) {
            byte[] buffer = new byte[1024];
            int len;
            while ((len = fis.read(buffer)) != -1) {
                System.out.println(new String(buffer, 0, len));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

BufferedInputStream / BufferedOutputStream

java
import java.io.*;

public class BufferedStreamDemo {
    public static void main(String[] args) {
        // 使用缓冲流复制文件
        try (
            BufferedInputStream bis = new BufferedInputStream(
                new FileInputStream("source.txt")
            );
            BufferedOutputStream bos = new BufferedOutputStream(
                new FileOutputStream("target.txt")
            )
        ) {
            byte[] buffer = new byte[8192];
            int len;
            while ((len = bis.read(buffer)) != -1) {
                bos.write(buffer, 0, len);
            }
            bos.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

字符流

FileReader / FileWriter

java
import java.io.*;

public class FileReaderDemo {
    public static void main(String[] args) {
        // 写入文件
        try (FileWriter fw = new FileWriter("test.txt")) {
            fw.write("Hello, Java!\n");
            fw.write("你好,世界!");
        } catch (IOException e) {
            e.printStackTrace();
        }
        
        // 读取文件
        try (FileReader fr = new FileReader("test.txt")) {
            char[] buffer = new char[1024];
            int len;
            while ((len = fr.read(buffer)) != -1) {
                System.out.print(new String(buffer, 0, len));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

BufferedReader / BufferedWriter

java
import java.io.*;

public class BufferedReaderDemo {
    public static void main(String[] args) {
        // 写入文件
        try (BufferedWriter bw = new BufferedWriter(
                new FileWriter("test.txt")
        )) {
            bw.write("第一行");
            bw.newLine();  // 换行
            bw.write("第二行");
        } catch (IOException e) {
            e.printStackTrace();
        }
        
        // 读取文件(按行)
        try (BufferedReader br = new BufferedReader(
                new FileReader("test.txt")
        )) {
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

转换流

InputStreamReader / OutputStreamWriter

java
import java.io.*;

public class ConvertStreamDemo {
    public static void main(String[] args) {
        // 指定编码读取
        try (
            InputStreamReader isr = new InputStreamReader(
                new FileInputStream("test.txt"), "UTF-8"
            );
            BufferedReader br = new BufferedReader(isr)
        ) {
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        
        // 指定编码写入
        try (
            OutputStreamWriter osw = new OutputStreamWriter(
                new FileOutputStream("test.txt"), "UTF-8"
            );
            BufferedWriter bw = new BufferedWriter(osw)
        ) {
            bw.write("你好,世界!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

文件操作

File类

java
import java.io.File;
import java.io.IOException;

public class FileDemo {
    public static void main(String[] args) throws IOException {
        // 创建File对象
        File file = new File("test.txt");
        File dir = new File("mydir/subdir");
        
        // 创建目录
        dir.mkdirs();
        
        // 创建文件
        if (!file.exists()) {
            file.createNewFile();
        }
        
        // 文件信息
        System.out.println("文件名: " + file.getName());
        System.out.println("路径: " + file.getPath());
        System.out.println("绝对路径: " + file.getAbsolutePath());
        System.out.println("大小: " + file.length() + " 字节");
        System.out.println("是否文件: " + file.isFile());
        System.out.println("是否目录: " + file.isDirectory());
        System.out.println("是否隐藏: " + file.isHidden());
        System.out.println("最后修改: " + file.lastModified());
        
        // 列出目录内容
        File[] files = dir.listFiles();
        if (files != null) {
            for (File f : files) {
                System.out.println(f.getName());
            }
        }
        
        // 删除文件
        file.delete();
    }
}

递归遍历目录

java
public static void listFiles(File dir, int level) {
    if (!dir.exists() || !dir.isDirectory()) {
        return;
    }
    
    File[] files = dir.listFiles();
    if (files == null) return;
    
    String indent = "  ".repeat(level);
    for (File file : files) {
        System.out.println(indent + file.getName());
        if (file.isDirectory()) {
            listFiles(file, level + 1);
        }
    }
}

对象序列化

Serializable接口

java
import java.io.*;

public class Person implements Serializable {
    private static final long serialVersionUID = 1L;
    
    private String name;
    private transient int age;  // 不参与序列化
    
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    @Override
    public String toString() {
        return "Person{name='" + name + "', age=" + age + "}";
    }
}

public class SerializationDemo {
    public static void main(String[] args) {
        Person person = new Person("张三", 25);
        
        // 序列化
        try (ObjectOutputStream oos = new ObjectOutputStream(
                new FileOutputStream("person.dat")
        )) {
            oos.writeObject(person);
            System.out.println("序列化成功");
        } catch (IOException e) {
            e.printStackTrace();
        }
        
        // 反序列化
        try (ObjectInputStream ois = new ObjectInputStream(
                new FileInputStream("person.dat")
        )) {
            Person p = (Person) ois.readObject();
            System.out.println("反序列化: " + p);
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

标准输入输出

System.in / System.out

java
import java.io.*;
import java.util.Scanner;

public class StandardIODemo {
    public static void main(String[] args) {
        // 使用Scanner读取标准输入
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入姓名: ");
        String name = scanner.nextLine();
        System.out.println("你好, " + name);
        
        // 使用BufferedReader
        try (BufferedReader br = new BufferedReader(
                new InputStreamReader(System.in)
        )) {
            System.out.print("请输入年龄: ");
            int age = Integer.parseInt(br.readLine());
            System.out.println("年龄: " + age);
        } catch (IOException e) {
            e.printStackTrace();
        }
        
        // 标准错误输出
        System.err.println("这是错误信息");
        
        // 重定向
        try {
            System.setOut(new PrintStream("output.txt"));
            System.out.println("这会写入文件");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}

字节数组流

ByteArrayInputStream / ByteArrayOutputStream

java
import java.io.*;

public class ByteArrayStreamDemo {
    public static void main(String[] args) {
        // 写入字节数组
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        baos.write("Hello".getBytes());
        baos.write(" World".getBytes());
        
        byte[] data = baos.toByteArray();
        System.out.println(new String(data));
        
        // 从字节数组读取
        ByteArrayInputStream bais = new ByteArrayInputStream(data);
        int b;
        while ((b = bais.read()) != -1) {
            System.out.print((char) b);
        }
    }
}

IO流选择指南

场景推荐流
读写二进制文件FileInputStream / FileOutputStream
读写文本文件BufferedReader / BufferedWriter
高效读写BufferedInputStream / BufferedOutputStream
指定编码读写InputStreamReader / OutputStreamWriter
对象持久化ObjectInputStream / ObjectOutputStream
内存中操作ByteArrayInputStream / ByteArrayOutputStream
标准输入输出System.in / System.out / Scanner