java 中怎么读取字符串
- 后端开发
- 2025-08-16
- 7
在 Java 编程中,读取字符串是一项基础且高频的操作,其实现方式需根据输入来源(如控制台、文件、网络流等)选择合适的工具类与方法,以下将从多维度展开详细说明,涵盖主流场景、核心代码、注意事项及对比分析,并提供实用示例与常见问题解答。
按输入来源分类的核心实现方案
从标准输入(控制台)读取字符串
适用于交互式命令行程序,典型工具为 java.util.Scanner 和 java.io.BufferedReader。
| 工具类 | 核心方法 | 特点 | 适用场景 |
|---|---|---|---|
| Scanner | nextLine() | 自动跳过空白行,支持正则表达式过滤(如 next("\d+") 读数字) | 简单交互、混合类型输入解析 |
| BufferedReader | readLine() | 逐行读取,保留换行符前的完整内容,性能优于 Scanner | 高性能控制台输入、长文本处理 |
| Console (JDK 6+) | readLine() | 直接关联系统控制台,无需额外包装 | 跨平台兼容的控制台交互 |
示例 1:使用 Scanner 读取单行字符串
import java.util.Scanner; public class ReadStringExample { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); // 绑定标准输入流 System.out.print("请输入内容: "); String input = scanner.nextLine(); // 读取整行(含空格) System.out.println("你输入的是: " + input); scanner.close(); // 释放资源 } }
️ 注意:next() 仅读取到下一个空白字符前,而 nextLine() 会读取整行(包括前后空格),若混合使用两者可能导致残留换行符问题。
示例 2:使用 BufferedReader 提升性能
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class FastReadExample { public static void main(String[] args) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); System.out.print("请输入内容: "); String line = reader.readLine(); // 阻塞等待用户输入 System.out.println("你输入的是: " + line); reader.close(); // 关闭流 } }
优势:BufferedReader 内部维护缓冲区,减少底层 I/O 次数,适合高频次、大数据量的输入。
从文件中读取字符串
涉及文件路径定位与字符编码处理,常用组合为 FileReader + BufferedReader 或 Files.readAllBytes(Java 7+)。

| 方案 | 关键代码 | 特点 | 局限性 |
|---|---|---|---|
| 传统流式读取 | new FileReader(filePath) → BufferedReader | 灵活控制读取进度,可逐行/按字符读取 | 需手动管理资源关闭 |
| NIO 文件API | Files.readAllBytes(Paths.get(filePath)) | 一次性读取全部内容到字节数组,配合 new String() 转换 | 大文件易导致内存溢出 |
| 第三方库(Apache Commons IO) | FileUtils.readFileToString(new File(filePath), StandardCharsets.UTF_8) | 一行代码完成,自动处理编码与异常 | 依赖外部库 |
示例 3:逐行读取文件内容
import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; public class FileReadExample { public static void main(String[] args) { String filePath = "data.txt"; try (BufferedReader br = new BufferedReader(new FileReader(filePath))) { String line; while ((line = br.readLine()) != null) { // 逐行读取直至文件末尾 System.out.println(line); } } catch (IOException e) { e.printStackTrace(); } } }
️ 关键细节:
- 字符编码:默认使用平台编码(如 Windows 的 GBK),建议显式指定 UTF-8 等编码,可通过 InputStreamReader 构造函数设置。
- 资源管理:使用 try-with-resources 语法自动关闭流,避免内存泄漏。
- 大文件优化:对于超过内存容量的文件,应改用 RandomAccessFile 或内存映射文件(MappedByteBuffer)。
从网络流中读取字符串
常见于 HTTP 请求响应、Socket 通信等场景,核心是通过 InputStream 转换为字符流。
示例 4:通过 URLConnection 读取网页内容


import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.URL; import java.net.URLConnection; public class WebReadExample { public static void main(String[] args) { try { URL url = new URL("http://example.com"); URLConnection connection = url.openConnection(); // 设置请求头(可选) connection.setRequestProperty("User-Agent", "Mozilla/5.0"); try (BufferedReader reader = new BufferedReader( new InputStreamReader(connection.getInputStream(), "UTF-8"))) { String line; while ((line = reader.readLine()) != null) { System.out.println(line); } } } catch (Exception e) { e.printStackTrace(); } } }
要点:
- 网络流本质是字节流,需通过 InputStreamReader 解码为字符流。
- 注意处理 HTTP 状态码(如 404 Not Found),可通过 connection.getResponseCode() 判断。
- 超时设置:connection.setConnectTimeout(5000); 防止长时间阻塞。
通用技巧与最佳实践
字符编码问题
- 痛点:不同系统默认编码不一致(如 Linux 多为 UTF-8,Windows 为 GBK),直接读取可能出现乱码。
- 解决方案:始终显式指定编码格式, new InputStreamReader(inputStream, StandardCharsets.UTF_8);
- 验证方法:打印字符串的字节数组查看是否符合预期。
异常处理策略
- 受检异常:IOException 必须捕获或声明抛出,推荐使用 try-catch 块。
- 非受检异常:如 NullPointerException(未初始化流)、UnsupportedEncodingException(错误编码名),需提前校验参数。
- 日志记录:生产环境建议将异常堆栈写入日志而非直接打印。
性能考量
| 场景 | 推荐方案 | 原因 |
|---|---|---|
| 小数据量(<1MB) | Scanner 或 BufferedReader | 开发便捷,开销可忽略 |
| 中等数据量(1-10MB) | BufferedReader + 合理缓冲区大小 | 平衡性能与内存占用 |
| 大数据量(>10MB) | 内存映射文件(MappedByteBuffer) | 直接操作磁盘,避免频繁 I/O |
| 实时流处理 | CompletableFuture + 异步读取 | 结合 Reactor 模式提升吞吐量 |
相关问答 FAQs
Q1: 为什么有时用 Scanner.nextLine() 会跳过预期的输入行?
A: 这是由于 Scanner 的内部机制导致的,当之前使用了 nextInt()、nextDouble() 等方法后,这些方法不会消耗行尾的换行符,导致后续的 nextLine() 立即读取到一个空行。
解决方法:在使用数值型方法后,添加一个额外的 nextLine() 消耗残留的换行符。
示例:
Scanner scanner = new Scanner(System.in); int age = scanner.nextInt(); // 输入年龄后按回车 scanner.nextLine(); // 消耗换行符 String name = scanner.nextLine(); // 现在能正确读取姓名
Q2: 如何高效读取非常大的文本文件(如几个GB)?
A: 对于超大文件,应采用以下策略:
- 分块读取:使用 BufferedReader 并设置较大的缓冲区(如 8KB),减少 I/O 次数。
- 并行处理:将文件拆分为多个部分,使用多线程或分布式框架(如 Spark)并行处理。
- 内存映射:通过 FileChannel.map() 将文件映射到内存,直接操作字节缓冲区。
示例(分块读取): import java.io.; import java.nio.charset.StandardCharsets;
public class LargeFileReader {
public static void main(String[] args) throws IOException {
File file = new File(“large.log”);
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8), 8 1024)) {
String line;
while ((line = reader.readLine()) != null) {
// 处理每一行…
}
}
}
}
--- 四、 Java 提供了丰富的字符串读取方案,选择时需综合考虑输入来源、数据量级、性能需求和编码兼容性,对于初学者,`Scanner` 和 `BufferedReader` 是入门首选;对于企业级应用,建议结合 NIO 或第三方库实现高效可靠的文件操作,无论何种场景,始终注意资源管理和异常处理