【Java】 Java 中的 BufferedReader 详解


我听见有人猜
你是敌人潜伏的内线
和你相知多年
我确信对你的了解
你舍命救我画面
一一在眼前浮现
司空见惯了鲜血
你忘记你本是娇娆的红颜
感觉你我彼此都那么依恋
                     🎵 许嵩《内线》


在 Java 中,处理文件输入和输出操作时,BufferedReader 是一个非常常用的类。它属于 Java I/O(输入/输出)系统中的高级类,通常用于高效地读取字符输入,特别是读取文本文件的内容。相比于低级的输入流类,BufferedReader 提供了更高效的读取方式,尤其适合逐行读取文本的场景。

在这篇博客中,我们将详细介绍 Java 中的 BufferedReader 类的用法、它的底层原理以及它的适用场景。

1. 什么是 BufferedReader?

BufferedReader 是 Java 中的一个类,位于 java.io 包中,它用于从字符输入流中读取文本,提供了缓冲功能以提高读取效率。与直接从输入流读取字符相比,BufferedReader 提供了一种更高效的方法,因为它在读取数据时使用了缓冲区,从而减少了对底层 I/O 操作系统的频繁访问。

BufferedReader 通常结合 FileReader 使用,用于读取文本文件中的字符。它的缓冲机制使得读取操作比 FileReader 更加高效,特别是在处理大文件时。

类的基本结构:

public class BufferedReader extends Reader

BufferedReader 继承了 Reader 类,并且提供了额外的缓冲功能和一些便捷方法,例如 readLine(),用于按行读取文本。

2. BufferedReader 的常用构造方法

BufferedReader 的构造方法有多个重载版本,常用的构造方法如下:

BufferedReader(Reader in)
BufferedReader(Reader in, int sz)

BufferedReader(Reader in):通过传入一个 Reader 对象(例如 FileReader)来创建一个带有默认缓冲区大小的 BufferedReader。
BufferedReader(Reader in, int sz):通过传入一个 Reader 对象和缓冲区大小 sz 来创建 BufferedReader。
通常,我们使用第一个构造方法即可,它使用系统默认的缓冲区大小(8192 字节),适合大多数应用场景。

3. BufferedReader 的基本用法

3.1 逐行读取文件

BufferedReader 的 readLine() 方法可以逐行读取文件内容,每次返回一行文本,直到到达文件末尾返回 null。

下面是一个使用 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("example.txt"))) {String line;// 使用 readLine() 方法逐行读取文件内容while ((line = br.readLine()) != null) {System.out.println(line);}} catch (IOException e) {e.printStackTrace();}}
}

输出示例:
假设 example.txt 文件内容如下:

Hello, World!
This is a test file.
BufferedReader makes reading easier.

程序的输出将是:

Hello, World!
This is a test file.
BufferedReader makes reading easier.

在这个例子中,我们使用 BufferedReader 的 readLine() 方法逐行读取文本文件的内容。每当 readLine() 读取到文件末尾时,会返回 null,从而结束读取循环。

3.2 使用 read(char[] cbuf) 读取多个字符

除了 readLine() 方法,BufferedReader 还提供了 read(char[] cbuf) 方法,可以一次性读取多个字符并将其存储到字符数组中。

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;public class BufferedReaderCharExample {public static void main(String[] args) {try (BufferedReader br = new BufferedReader(new FileReader("example.txt"))) {char[] buffer = new char[1024];  // 创建字符缓冲区int bytesRead;// 读取文件中的字符while ((bytesRead = br.read(buffer)) != -1) {System.out.println(new String(buffer, 0, bytesRead));}} catch (IOException e) {e.printStackTrace();}}
}

在这个例子中,read(char[] cbuf) 方法一次读取多个字符并将它们存储在字符数组中,然后将这些字符输出到控制台。

4. BufferedReader 的常用方法

BufferedReader 提供了多种方法用于读取数据,以下是其中一些常用的方法:

4.1 String readLine()

readLine() 方法用于逐行读取文件内容。每次调用它会返回一行文本,直到遇到行尾。如果到达文件末尾,返回 null。

String line = br.readLine();
4.2 int read()

read() 方法用于读取单个字符,返回该字符的整数表示(即字符的 Unicode 值)。如果到达流的末尾,返回 -1。

int character = br.read();
4.3 int read(char[] cbuf)

read(char[] cbuf) 方法用于一次性读取多个字符并将它们存储在字符数组 cbuf 中,返回实际读取的字符数量。如果到达文件末尾,返回 -1。

int bytesRead = br.read(buffer);
4.4 void close()

close() 方法用于关闭流并释放与该流关联的所有资源。通常在完成读取操作后应该调用此方法。使用 try-with-resources 语句时会自动关闭流。

br.close();

5. BufferedReader 的性能优势

与直接使用 FileReader 或 InputStreamReader 相比,BufferedReader 的最大优势在于它使用了 缓冲区,这显著提高了文件读取的效率。

减少 I/O 操作:BufferedReader 不会每读取一个字符就访问文件,而是一次性将一块数据(通常是 8KB)读取到内存缓冲区中,然后在缓冲区内逐字节读取数据。这种缓冲机制减少了与文件系统的交互次数,提升了读取速度。
适合逐行读取:BufferedReader 的 readLine() 方法提供了按行读取文本的功能,非常适合处理文本文件(如日志文件、配置文件等),比逐字节读取更方便。
处理大文件:对于大文件,BufferedReader 可以有效避免因频繁读取导致的性能瓶颈,能够更加高效地处理大文件内容。

6. BufferedReader 的适用场景

BufferedReader 主要用于处理以下场景:

读取文本文件:当你需要读取大文本文件并按行处理时,BufferedReader 是最佳选择。
日志文件处理:逐行读取日志文件内容进行分析、过滤或查找特定信息。
配置文件解析:读取配置文件中的每一行并进行解析或处理。
从网络流读取数据:BufferedReader 也可用于读取网络输入流(如从服务器接收文本数据)。

7. 实际案例:统计文件中的行数

以下示例展示了如何使用 BufferedReader 来统计文件中的行数:

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;public class LineCountExample {public static void main(String[] args) {int lineCount = 0;try (BufferedReader br = new BufferedReader(new FileReader("example.txt"))) {while (br.readLine() != null) {lineCount++;}System.out.println("文件中的行数是:" + lineCount);} catch (IOException e) {e.printStackTrace();}}
}

输出:
假设 example.txt 文件内容有 3 行,输出将为:

文件中的行数是:3

在这个示例中,程序通过不断调用 readLine() 来统计文件中的行数,直到到达文件末尾。

8. 使用 BufferedReader 与 BufferedWriter

当需要进行文件的读写操作时,BufferedReader 常与 BufferedWriter 搭配使用,前者用于高效读取文件,后者用于高效写入文件。两者都具有缓冲功能,能够显著提升 I/O 操作的性能。
示例:将一个文件复制到另一个文件

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;public class FileCopyExample {public static void main(String[] args) {try (BufferedReader br = new BufferedReader(new FileReader("input.txt"));BufferedWriter bw = new BufferedWriter(new FileWriter("output.txt"))) {String line;while ((line = br.readLine()) != null) {bw.write(line);bw.newLine();  // 写入换行符}} catch (IOException e) {e.printStackTrace();}}
}

在这个例子中,BufferedReader 逐行读取 input.txt 文件的内容,并通过 BufferedWriter 将其逐行写入到 output.txt 中。

9. BufferedReader 的局限性

虽然 BufferedReader 非常适合处理字符流输入,尤其是文本文件,但它也有一些局限性:

不适合处理二进制文件:BufferedReader 是专门为字符流设计的,不适合用于处理二进制数据(如图片、音频、视频等)。对于这些文件类型,应该使用 BufferedInputStream 或 FileInputStream。
编码问题:默认情况下,FileReader 使用系统默认的字符编码,这可能会导致编码问题。如果文件使用非默认编码,建议使用 InputStreamReader 来指定文件编码。

10. 总结

BufferedReader 是 Java I/O 系统中一个非常强大的工具,尤其适合处理文本文件的读取。它的缓冲机制有效地提升了文件读取的效率,特别是在处理大文件或逐行读取内容时非常有用。相比于低级的文件读取类,BufferedReader 提供了更加简洁、易用的接口,使得开发者能够以更高效的方式处理文本数据。

当你需要读取文本文件,尤其是需要逐行处理时,BufferedReader 是一个非常合适的选择。通过结合 FileReader、BufferedWriter 等类,BufferedReader 能够轻松实现文件的高效读写操作,是 Java 文件 I/O 操作中的重要工具。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/51836.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何开发一款流畅、稳定、有趣味性的棋类游戏?

开发一款流畅、稳定且具有趣味性的棋类游戏,需要从多个角度出发,进行全面的设计和技术实现。以下是开发过程中的关键要素: 1. 明确游戏规则与玩法设计: 首先,确定棋类游戏的基本规则和核心玩法。规则需要严谨而不复杂…

HarmonyOS Next 系列之列表下拉刷新和触底加载更多数据实现(十一)

系列文章目录 HarmonyOS Next 系列之省市区弹窗选择器实现(一) HarmonyOS Next 系列之验证码输入组件实现(二) HarmonyOS Next 系列之底部标签栏TabBar实现(三) HarmonyOS Next 系列之HTTP请求封装和Token…

东南大学:Wi-Fi 6搭档全光以太,打造“数智东南”信息高速路

东南大学:Wi-Fi 6搭档全光以太,打造“数智东南”信息高速路 - 华为企业业务 打好ICT底座,平台和应用层面就会非常通畅了。首先,出海企业的需求既有普遍性,也有垂直性行业的特性需求。普遍性需求需要通信、沟通数据和传…

虚幻反射-

在Unreal Engine中,如果你想获取一个AActor中的所有FProperty,可以使用TFieldIterator来遍历特定类的属性。以下是一些关键步骤和示例代码: 包含必要的头文件:首先,确保包含了反射相关的头文件。 #include "Engin…

GB/T 26825-2011 FJ抗静电防腐胶检测

FJ抗静电防腐胶是指涂覆于石油、化工贮运设备或建筑物室内地面上,能够防止静电积累并疏导静电快速释放的防腐蚀材料。 GB/T 26825-2011 FJ抗静电防腐胶检测项目: 测试项目 测试方法 干燥时间 GB/T 1728 硬度 GB/T 6739 粘接强度 GB/T 26825 抗压…

Golang | Leetcode Golang题解之第337题打家劫舍III

题目: 题解: func rob(root *TreeNode) int {val : dfs(root)return max(val[0], val[1]) }func dfs(node *TreeNode) []int {if node nil {return []int{0, 0}}l, r : dfs(node.Left), dfs(node.Right)selected : node.Val l[1] r[1]notSelected : …

Kali Linux网络问题解决与静态IP配置技巧

很多用户在使用 Kali Linux 时会遇到无法联网的问题,尤其是在 VMware 虚拟机中。这种情况相当常见,一般都是没有配置DNS服务器或者网卡配置文件的IP和虚拟网络编辑器的IP不一致所导致的,下面我们将探讨如何在 Kali Linux 中配置 DNS 服务和设…

mysql windows安装与远程连接配置

安装包在主页资源中 一、安装(此安装教程为“mysql-installer-community-5.7.41.0.msi”安装教程,安装到win10环境) 保持默认选项,点击”Next“。 点开第一行加号展开一路展开找到“MySQL Server 5,7,41 - X64”点击选中点击一下中间只想右侧的箭头看到…

Element-02.组件-Table表格

一.常见组件-表格 二.具体操作 <template><el-table:data"tableData"borderstyle"width: 100%"><el-table-columnprop"date"label"日期"width"180"></el-table-column><el-table-columnprop&q…

SQL - 事务

事务是代表单个工作单元的一组SQL语句&#xff0c;当我们需要对数据库进行多次更改的情况下&#xff0c;要使用事务&#xff0c;我们希望所有这些更改作为一个单元一起成功或失败事务属性 (ACID) 原子性(Atomicity)&#xff1a;事务中的所有操作要么全部完成&#xff0c;要么全…

各种文件的预览下载(docx,pdf,txt,图片)

一、word 1、word的预览可以用onlyoffice 2、word的预览下载 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title></head><body><div onclick"FilehandleClick()">word文件</…

Android -- 谷歌地图绘制

引言 集成之后&#xff0c;在项目中肯定要打点&#xff0c;画线&#xff08;实线&#xff0c;虚线&#xff09;&#xff0c;绘制区域等。 Android 谷歌地图绘制轨迹polyline 在Android中使用Google Maps绘制轨迹polyline的基本步骤如下&#xff1a; 确保你的项目已经正确集成…

spring:Springboot升级到最新的3.0或者java8升级到java17所需要的改动(持续更新)

背景 Spring Boot 2.x 升级到 Spring Boot 3.x 需要使用Java 17或更高版本&#xff0c;所以有些地方需要改动 pom.xml文件改动 修改pom.xml文件&#xff0c;version版本根据实际情况配置最新。 <!-- java.version版本8更换为17 --> <java.version>17</java.…

JS中链式调用的实现和应用

你好同学&#xff0c;我是沐爸&#xff0c;欢迎点赞、收藏和关注。个人知乎 不知你是否注意过&#xff0c;链式调用在编程中还是很普遍的&#xff0c;无论是原生JavaScript还是在一些框架和库中&#xff0c;都会看到它们的身影。今天我们一探究竟&#xff0c;看下链式调用是怎么…

Chat App 项目之解析(二)

Chat App 项目介绍与解析&#xff08;一&#xff09;-CSDN博客文章浏览阅读76次。Chat App 是一个实时聊天应用程序&#xff0c;旨在为用户提供一个简单、直观的聊天平台。该应用程序不仅支持普通用户的注册和登录&#xff0c;还提供了管理员登录功能&#xff0c;以便管理员可以…

MongoDB数据类型介绍

MongoDB作为一种高性能、开源、无模式的文档型数据库&#xff0c;支持丰富的数据类型&#xff0c;以满足各种复杂的数据存储需求。本文将详细介绍MongoDB支持的主要数据类型&#xff0c;包括数值类型、字符串类型、日期和时间类型、布尔类型、二进制类型、数组、对象以及其他扩…

SpringBoot项目部署时application.yml文件的加载优先级和启动脚本

文章目录 application.yml文件的加载优先级(由高到低)第一级命令行参数第二级Jar包同级目录 /config第三级Jar包同级目录第四级classpath 下的/config第五级classpath 根路径/总结&#xff1a; logback.xml 文件加载顺序当application.yml 和 bootstrap.yml 同时存在时java jar…

【iOS】Block底层分析

目录 前言Block底层结构Block捕获变量原理捕获局部变量&#xff08;auto、static&#xff09;全局变量捕获实例self Block类型Block的copyBlock作为返回值将Block赋值给__strong指针Block作为Cocoa API中方法名含有usingBlock的方法参数Block作为GCD API的方法参数Block属性的写…

使用QGraphicsView思想做一个简单图片查看器

使用QGraphicsView思想做一个简单图片查看器 如果要做一个图片查看器&#xff0c;支持放大、滚动操作&#xff0c;比较直接的方法是&#xff0c;使用QWidget来显示完整图片&#xff0c;将QWidget放入QScrollArea。缩放时调整QWidget的尺寸&#xff0c;QScrollArea会自动调整滚…

MBR20200FCT-ASEMI智能AI专用MBR20200FCT

编辑&#xff1a;ll MBR20200FCT-ASEMI智能AI专用MBR20200FCT 型号&#xff1a;MBR20200FCT 品牌&#xff1a;ASEMI 封装&#xff1a;TO-220F 批号&#xff1a;最新 最大平均正向电流&#xff08;IF&#xff09;&#xff1a;20A 最大循环峰值反向电压&#xff08;VRRM&a…