跳转至

Java 中读取标准输入(Read Stdin)

简介

在 Java 编程中,读取标准输入(stdin)是一项常见的操作。标准输入是程序接收用户输入的主要方式之一,无论是在控制台应用程序中获取用户的指令,还是在开发工具中进行调试时获取测试数据,都需要从标准输入读取数据。本文将深入探讨在 Java 中如何读取标准输入,包括基础概念、不同的使用方法、常见实践以及最佳实践。

目录

  1. 基础概念
  2. 使用方法
    • 使用 Scanner 类
    • 使用 BufferedReader 类
    • 使用 InputStreamReader 和 System.in
  3. 常见实践
    • 读取整数
    • 读取字符串
    • 读取一行数据
  4. 最佳实践
    • 异常处理
    • 资源管理
  5. 小结
  6. 参考资料

基础概念

标准输入(stdin)是操作系统提供给程序的一个输入流。在大多数操作系统中,通常可以通过键盘输入数据到标准输入流,然后程序可以从这个流中读取数据。在 Java 中,标准输入通过 System.in 来表示,它是一个 InputStream 类型的对象。InputStream 是一个字节输入流,用于从源读取字节数据。然而,在实际应用中,我们往往需要读取更高级的数据类型,如字符串、整数等,这就需要借助一些辅助类来处理输入。

使用方法

使用 Scanner 类

Scanner 类是 Java 中用于读取用户输入的常用类,它位于 java.util 包中。Scanner 类提供了多种方法来读取不同类型的数据,使用起来非常方便。

import java.util.Scanner;

public class ScannerExample {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入一个整数:");
        int number = scanner.nextInt();
        System.out.println("你输入的整数是: " + number);

        System.out.println("请输入一个字符串:");
        String str = scanner.next();
        System.out.println("你输入的字符串是: " + str);

        scanner.close();
    }
}

在上述代码中: 1. 首先创建了一个 Scanner 对象,它以 System.in 作为输入源。 2. 使用 nextInt() 方法读取一个整数,使用 next() 方法读取一个字符串。 3. 最后调用 close() 方法关闭 Scanner 对象,释放资源。

使用 BufferedReader 类

BufferedReader 类位于 java.io 包中,它提供了缓冲功能,可以提高读取效率。通常与 InputStreamReader 一起使用,将字节流转换为字符流。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class BufferedReaderExample {
    public static void main(String[] args) {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        try {
            System.out.println("请输入一行数据:");
            String line = reader.readLine();
            System.out.println("你输入的内容是: " + line);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

在这段代码中: 1. 创建了一个 BufferedReader 对象,它通过 InputStreamReaderSystem.in 转换为字符流。 2. 使用 readLine() 方法读取一行数据。 3. 使用 try-catch-finally 块来处理可能的 IOException 异常,并在最后关闭 BufferedReader 对象。

使用 InputStreamReader 和 System.in

直接使用 InputStreamReaderSystem.in 也可以读取标准输入,但这种方式相对底层,使用起来不够方便。

import java.io.IOException;
import java.io.InputStreamReader;

public class InputStreamReaderExample {
    public static void main(String[] args) {
        InputStreamReader reader = new InputStreamReader(System.in);
        try {
            System.out.println("请输入一个字符:");
            int charInt = reader.read();
            char ch = (char) charInt;
            System.out.println("你输入的字符是: " + ch);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

在这个例子中: 1. 创建了一个 InputStreamReader 对象,将 System.in 转换为字符流。 2. 使用 read() 方法读取一个字符,返回的是字符的 ASCII 码值,需要进行类型转换。 3. 同样使用 try-catch-finally 块处理异常并关闭资源。

常见实践

读取整数

读取整数是常见的需求,使用 Scanner 类非常简单:

import java.util.Scanner;

public class ReadIntegerExample {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入一个整数:");
        int number = scanner.nextInt();
        System.out.println("你输入的整数是: " + number);
        scanner.close();
    }
}

读取字符串

读取字符串也很常见,Scanner 类的 next() 方法可以读取一个单词,nextLine() 方法可以读取一整行:

import java.util.Scanner;

public class ReadStringExample {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入一个单词:");
        String word = scanner.next();
        System.out.println("你输入的单词是: " + word);

        System.out.println("请输入一行内容:");
        scanner.nextLine(); // 消耗掉上一次输入的换行符
        String line = scanner.nextLine();
        System.out.println("你输入的内容是: " + line);

        scanner.close();
    }
}

读取一行数据

使用 BufferedReader 类读取一行数据非常方便:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class ReadLineExample {
    public static void main(String[] args) {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        try {
            System.out.println("请输入一行数据:");
            String line = reader.readLine();
            System.out.println("你输入的内容是: " + line);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

最佳实践

异常处理

在读取标准输入时,可能会发生各种异常,如 IOExceptionInputMismatchException 等。使用 try-catch 块来捕获并处理这些异常是非常重要的。

import java.util.InputMismatchException;
import java.util.Scanner;

public class ExceptionHandlingExample {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        try {
            System.out.println("请输入一个整数:");
            int number = scanner.nextInt();
            System.out.println("你输入的整数是: " + number);
        } catch (InputMismatchException e) {
            System.out.println("输入的不是一个有效的整数");
        } finally {
            scanner.close();
        }
    }
}

资源管理

无论是 ScannerBufferedReader 还是 InputStreamReader,都需要在使用完毕后关闭,以释放资源。可以使用 try-with-resources 语句来自动关闭资源,使代码更简洁、安全。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class ResourceManagementExample {
    public static void main(String[] args) {
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) {
            System.out.println("请输入一行数据:");
            String line = reader.readLine();
            System.out.println("你输入的内容是: " + line);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

小结

在 Java 中读取标准输入有多种方法,每种方法都有其特点和适用场景。Scanner 类使用方便,适用于读取各种类型的数据;BufferedReader 类提供了缓冲功能,适合读取大量数据或按行读取;直接使用 InputStreamReader 则更底层,灵活性较高。在实际应用中,需要根据具体需求选择合适的方法,并注意异常处理和资源管理,以确保程序的健壮性和高效性。

参考资料