跳转到内容

Java输入输出(I O)

来自代码酷

Java输入输出(I/O)[编辑 | 编辑源代码]

Java输入输出(Input/Output,简称I/O)是Java编程中处理数据流的核心机制,用于实现程序与外部设备(如文件、网络、控制台等)之间的数据交互。Java通过java.iojava.nio包提供了一套丰富的API来支持不同类型的I/O操作。

概述[编辑 | 编辑源代码]

Java I/O主要分为以下两类:

  • 输入流(Input Stream):用于从外部读取数据(如文件、键盘输入等)。
  • 输出流(Output Stream):用于向外部写入数据(如文件、控制台输出等)。

Java I/O流又可分为:

  • 字节流:以字节(8位)为单位操作数据,适用于二进制文件(如图片、音频等)。
  • 字符流:以字符(16位Unicode)为单位操作数据,适用于文本文件。

字节流[编辑 | 编辑源代码]

字节流的核心类是InputStreamOutputStream,它们是所有字节流类的父类。

文件读写示例[编辑 | 编辑源代码]

以下是一个使用字节流读写文件的示例:

import java.io.*;

public class FileByteStreamExample {
    public static void main(String[] args) {
        // 写入文件
        try (OutputStream out = new FileOutputStream("example.txt")) {
            String content = "Hello, Java I/O!";
            out.write(content.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 读取文件
        try (InputStream in = new FileInputStream("example.txt")) {
            int data;
            while ((data = in.read()) != -1) {
                System.out.print((char) data);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

输出:

Hello, Java I/O!

解释:

  • FileOutputStream 将字符串转换为字节并写入文件。
  • FileInputStream 逐字节读取文件内容并转换为字符输出。

字符流[编辑 | 编辑源代码]

字符流的核心类是ReaderWriter,适用于文本数据处理。

文件读写示例[编辑 | 编辑源代码]

import java.io.*;

public class FileCharStreamExample {
    public static void main(String[] args) {
        // 写入文件
        try (Writer writer = new FileWriter("example.txt")) {
            writer.write("Java字符流示例");
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 读取文件
        try (Reader reader = new FileReader("example.txt")) {
            int data;
            while ((data = reader.read()) != -1) {
                System.out.print((char) data);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

输出:

Java字符流示例

缓冲流[编辑 | 编辑源代码]

为提高I/O效率,Java提供了BufferedInputStreamBufferedOutputStreamBufferedReaderBufferedWriter,它们通过内部缓冲区减少直接I/O操作次数。

示例[编辑 | 编辑源代码]

import java.io.*;

public class BufferedStreamExample {
    public static void main(String[] args) {
        // 使用缓冲流写入
        try (BufferedWriter bw = new BufferedWriter(new FileWriter("buffered.txt"))) {
            bw.write("缓冲流提高性能");
            bw.newLine();
            bw.write("减少磁盘I/O次数");
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 使用缓冲流读取
        try (BufferedReader br = new BufferedReader(new FileReader("buffered.txt"))) {
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

输出:

缓冲流提高性能
减少磁盘I/O次数

标准I/O[编辑 | 编辑源代码]

Java通过System.inSystem.outSystem.err提供标准输入/输出流。

控制台输入示例[编辑 | 编辑源代码]

import java.util.Scanner;

public class ConsoleInputExample {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入您的姓名: ");
        String name = scanner.nextLine();
        System.out.println("欢迎, " + name + "!");
        scanner.close();
    }
}

运行示例:

请输入您的姓名: 张三
欢迎, 张三!

对象序列化[编辑 | 编辑源代码]

Java可通过ObjectInputStreamObjectOutputStream实现对象的序列化与反序列化。

示例[编辑 | 编辑源代码]

import java.io.*;

class Person implements Serializable {
    String name;
    int age;

    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

public class ObjectStreamExample {
    public static void main(String[] args) {
        // 序列化
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.dat"))) {
            oos.writeObject(new Person("李四", 25));
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 反序列化
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.dat"))) {
            Person p = (Person) ois.readObject();
            System.out.println(p.name + ", " + p.age + "岁");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

输出:

李四, 25岁

NIO(New I/O)[编辑 | 编辑源代码]

Java NIO提供了更高效的I/O处理方式,核心组件包括:

  • Channel:双向数据传输通道
  • Buffer:数据容器
  • Selector:多路复用器

文件复制示例[编辑 | 编辑源代码]

import java.nio.*;
import java.nio.channels.*;
import java.nio.file.*;

public class NIOFileCopy {
    public static void main(String[] args) {
        Path source = Paths.get("source.txt");
        Path target = Paths.get("target.txt");
        
        try (FileChannel in = FileChannel.open(source, StandardOpenOption.READ);
             FileChannel out = FileChannel.open(target, StandardOpenOption.WRITE, 
                                              StandardOpenOption.CREATE)) {
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            while (in.read(buffer) != -1) {
                buffer.flip();
                out.write(buffer);
                buffer.clear();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

实际应用场景[编辑 | 编辑源代码]

1. 配置文件读取:使用Properties类加载.properties文件 2. 日志记录:通过FileWriter或BufferedWriter写入日志文件 3. 网络通信:Socket编程中的数据传输 4. 数据持久化:对象序列化保存用户数据

性能比较[编辑 | 编辑源代码]

barChart title I/O操作性能比较 x-axis 操作类型 y-axis 时间(ms) series 1MB文件 bar 字节流: 120 bar 字符流: 100 bar 缓冲流: 30 bar NIO: 20

最佳实践[编辑 | 编辑源代码]

1. 始终使用try-with-resources确保流关闭 2. 大文件处理优先使用缓冲流或NIO 3. 文本数据处理选择字符流 4. 二进制数据处理选择字节流 5. 考虑使用第三方库如Apache Commons IO简化操作

总结[编辑 | 编辑源代码]

Java I/O系统提供了灵活的数据处理方式,开发者应根据具体需求选择合适的流类型。对于现代应用,NIO提供了更好的性能和可扩展性,而传统I/O API在简单场景中仍具有优势。