On this page

Java输入和输出

Java 输入和输出 (I/O)

Java 提供了丰富的输入输出功能,主要通过 java.io 包和 java.util.Scanner 类实现。以下是 Java 中输入输出的主要方式。

一、标准输入输出

1. 标准输出 (System.out)

// System.out.print() - 不换行
System.out.print("Hello ");
System.out.print("World!");

// System.out.println() - 换行
System.out.println("Hello");
System.out.println("World");

// System.out.printf() - 格式化输出
String name = "Alice";
int age = 25;
System.out.printf("Name: %s, Age: %d%n", name, age);

2. 标准输入 (System.in)

使用 Scanner 类读取用户输入:

import java.util.Scanner;

public class StandardInput {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        System.out.print("请输入您的姓名: ");
        String name = scanner.nextLine();  // 读取整行
        
        System.out.print("请输入您的年龄: ");
        int age = scanner.nextInt();      // 读取整数
        
        System.out.print("请输入您的身高(米): ");
        double height = scanner.nextDouble();  // 读取双精度浮点数
        
        System.out.printf("姓名: %s, 年龄: %d, 身高: %.2f米%n", 
                         name, age, height);
        
        scanner.close();  // 关闭Scanner
    }
}

二、文件输入输出

1. 使用 Scanner 读取文件

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class FileReadExample {
    public static void main(String[] args) {
        try {
            File file = new File("input.txt");
            Scanner scanner = new Scanner(file);
            
            while (scanner.hasNextLine()) {
                String line = scanner.nextLine();
                System.out.println(line);
            }
            
            scanner.close();
        } catch (FileNotFoundException e) {
            System.out.println("文件未找到: " + e.getMessage());
        }
    }
}

2. 使用 BufferedReader 读取文件(更高效)

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class BufferedReaderExample {
    public static void main(String[] args) {
        try (BufferedReader br = new BufferedReader(new FileReader("input.txt"))) {
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            System.out.println("读取文件出错: " + e.getMessage());
        }
    }
}

3. 使用 FileWriter 写入文件

import java.io.FileWriter;
import java.io.IOException;

public class FileWriteExample {
    public static void main(String[] args) {
        try (FileWriter writer = new FileWriter("output.txt")) {
            writer.write("第一行\n");
            writer.write("第二行\n");
            writer.append("追加的内容\n");
            System.out.println("文件写入成功");
        } catch (IOException e) {
            System.out.println("写入文件出错: " + e.getMessage());
        }
    }
}

4. 使用 PrintWriter 写入文件(更灵活)

import java.io.PrintWriter;
import java.io.FileNotFoundException;

public class PrintWriterExample {
    public static void main(String[] args) {
        try (PrintWriter pw = new PrintWriter("data.txt")) {
            pw.println("姓名: 张三");
            pw.println("年龄: 25");
            pw.printf("成绩: %.2f%n", 89.5);
            System.out.println("数据写入成功");
        } catch (FileNotFoundException e) {
            System.out.println("文件未找到: " + e.getMessage());
        }
    }
}

三、对象序列化与反序列化

1. 序列化对象到文件

import java.io.*;

class Person implements Serializable {
    String name;
    int age;
    
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

public class ObjectSerialization {
    public static void main(String[] args) {
        Person person = new Person("李四", 30);
        
        try (ObjectOutputStream oos = 
             new ObjectOutputStream(new FileOutputStream("person.dat"))) {
            oos.writeObject(person);
            System.out.println("对象序列化成功");
        } catch (IOException e) {
            System.out.println("序列化失败: " + e.getMessage());
        }
    }
}

2. 从文件反序列化对象

import java.io.*;

public class ObjectDeserialization {
    public static void main(String[] args) {
        try (ObjectInputStream ois = 
             new ObjectInputStream(new FileInputStream("person.dat"))) {
            Person person = (Person) ois.readObject();
            System.out.println("姓名: " + person.name);
            System.out.println("年龄: " + person.age);
        } catch (IOException | ClassNotFoundException e) {
            System.out.println("反序列化失败: " + e.getMessage());
        }
    }
}

四、控制台与用户交互

1. 使用 Console 类(更安全)

import java.io.Console;

public class ConsoleExample {
    public static void main(String[] args) {
        Console console = System.console();
        if (console == null) {
            System.out.println("无法获取控制台");
            return;
        }
        
        String username = console.readLine("用户名: ");
        char[] password = console.readPassword("密码: ");
        
        console.printf("欢迎, %s%n", username);
        console.printf("密码长度: %d%n", password.length);
        
        // 清除密码字符数组
        java.util.Arrays.fill(password, ' ');
    }
}

2. 读取命令行参数

public class CommandLineArgs {
    public static void main(String[] args) {
        System.out.println("接收到 " + args.length + " 个参数");
        for (int i = 0; i < args.length; i++) {
            System.out.printf("参数 %d: %s%n", i, args[i]);
        }
    }
}

五、高级 I/O 操作

1. 使用 Files 类(Java 7+)

import java.nio.file.Files;
import java.nio.file.Paths;
import java.io.IOException;
import java.util.List;

public class FilesExample {
    public static void main(String[] args) {
        try {
            // 读取所有行
            List<String> lines = Files.readAllLines(Paths.get("input.txt"));
            for (String line : lines) {
                System.out.println(line);
            }
            
            // 写入文件
            String content = "新内容\n第二行";
            Files.write(Paths.get("output.txt"), content.getBytes());
            
            // 检查文件是否存在
            boolean exists = Files.exists(Paths.get("input.txt"));
            System.out.println("文件存在: " + exists);
        } catch (IOException e) {
            System.out.println("IO错误: " + e.getMessage());
        }
    }
}

2. 使用 try-with-resources 自动关闭资源

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class TryWithResources {
    public static void main(String[] args) {
        // Java 7+ 自动关闭资源
        try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            System.out.println("读取文件出错: " + e.getMessage());
        }
    }
}

六、注意事项

  1. 资源管理:始终关闭 I/O 资源,使用 try-with-resources 最佳
  2. 异常处理:妥善处理 IOException
  3. 字符编码:指定字符集(如 UTF-8)以避免乱码
  4. 路径问题:使用相对路径时注意当前工作目录
  5. 性能考虑
    • 大文件使用缓冲流(BufferedReader/BufferedWriter)
    • 二进制数据使用字节流(InputStream/OutputStream)
    • 文本数据使用字符流(Reader/Writer)

Java 的 I/O 系统非常强大,以上只是基础内容。根据具体需求,可以选择最适合的 I/O 方式。