Java IO 流:从字节到字符再到Java 装饰者模式(Decorator Pattern),解析与应用掌握数据流动的艺术
在 Java 编程中,IO(输入输出)流是处理数据输入输出的核心工具。无论是读取文件、网络通信,还是处理用户输入,IO 流都扮演着重要角色。本文将深入探讨 Java IO 流的核心概念、分类、经典代码实例及其应用场景,帮助你全面掌握数据流动的艺术。

1. Java IO 流的核心概念
1.1 什么是 IO 流?
IO 流是 Java 中用于处理输入输出数据的抽象概念。它可以将数据从一个地方(如文件、网络)传输到另一个地方(如内存、控制台)。
1.2 IO 流的分类
-
按数据单位:
-
字节流:以字节为单位读写数据,适用于二进制文件(如图片、视频)。
-
字符流:以字符为单位读写数据,适用于文本文件。
-
-
按流向:
-
输入流:从外部读取数据到程序中。
-
输出流:将程序中的数据写入外部。
-
2. Java IO 流的经典类
2.1 字节流
字节流主要用于处理二进制数据。Java 提供了 InputStream 和 OutputStream 作为字节流的基类。
-
InputStream:字节输入流的基类。
-
常用实现类:
FileInputStream、BufferedInputStream。
-
-
OutputStream:字节输出流的基类。
-
常用实现类:
FileOutputStream、BufferedOutputStream。
-
2.2 字符流
-
Reader:字符输入流的基类。
-
常用实现类:
FileReader、BufferedReader。
-
-
Writer:字符输出流的基类。
-
常用实现类:
FileWriter、BufferedWriter。
-
3. 经典代码实例
3.1 字节流:文件复制
以下是一个使用字节流复制文件的示例:
//代码解读:
//使用 FileInputStream 读取源文件。
//
//FileOutputStream 写入目标文件。
//
//通过缓冲区 byte[] buffer 提高读写效率。//使用 try-with-resources 语法自动关闭流。import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;public class ByteStreamExample {public static void main(String[] args) {try (FileInputStream fis = new FileInputStream("source.txt");FileOutputStream fos = new FileOutputStream("target.txt")) {byte[] buffer = new byte[1024];int length;while ((length = fis.read(buffer)) != -1) {fos.write(buffer, 0, length);}System.out.println("文件复制完成!");} catch (IOException e) {e.printStackTrace();}}
}
3.2 字符流:文本文件读取
以下是一个使用字符流读取文本文件的示例:
//代码解读:
//使用 FileReader 读取文本文件。//使用 BufferedReader 包装 FileReader,提高读取效率。通过 readLine() 方法逐行读取文件内容。
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;public class CharStreamExample {public static void main(String[] args) {try (BufferedReader br = new BufferedReader(new FileReader("source.txt"))) {String line;while ((line = br.readLine()) != null) {System.out.println(line);}} catch (IOException e) {e.printStackTrace();}}
}
3.3 缓冲流:高效文件读写
以下是一个使用缓冲流读写文件的示例:
//使用 BufferedReader 和 BufferedWriter 包装字符流,提高读写效率。//通过 readLine() 和 write() 方法逐行读写文件。
import java.io.*;public class BufferedStreamExample {public static void main(String[] args) {try (BufferedReader br = new BufferedReader(new FileReader("source.txt"));BufferedWriter bw = new BufferedWriter(new FileWriter("target.txt"))) {String line;while ((line = br.readLine()) != null) {bw.write(line);bw.newLine(); // 写入换行符}System.out.println("文件读写完成!");} catch (IOException e) {e.printStackTrace();}}
}
3.4 对象流:序列化与反序列化
Java 提供 ObjectOutputStream 和 ObjectInputStream 来进行对象的序列化和反序列化。
import java.io.*;class Person implements Serializable {private static final long serialVersionUID = 1L;private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Person{name='" + name + "', age=" + age + "}";}
}public class ObjectStreamExample {public static void main(String[] args) {String filePath = "person.ser";try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath))) {Person p = new Person("Alice", 25);oos.writeObject(p);} catch (IOException e) {e.printStackTrace();}try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath))) {Person p = (Person) ois.readObject();System.out.println("反序列化对象: " + p);} catch (IOException | ClassNotFoundException e) {e.printStackTrace();}}
}
3.5 转换流:示例
转换流 适用于字节与字符的转换,支持编码格式转换。
import java.io.*;public class ConvertStreamExample {public static void main(String[] args) {try (OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("example.txt"), "UTF-8")) {osw.write("你好,世界!");} catch (IOException e) {e.printStackTrace();}try (InputStreamReader isr = new InputStreamReader(new FileInputStream("example.txt"), "UTF-8")) {int data;while ((data = isr.read()) != -1) {System.out.print((char) data);}} catch (IOException e) {e.printStackTrace();}}
}
3.6 PrintStream 和 PrintWriter
import java.io.PrintStream;
import java.io.FileOutputStream;
import java.io.IOException;public class PrintStreamExample {public static void main(String[] args) {try (PrintStream ps = new PrintStream(new FileOutputStream("printStream.txt"))) {ps.println("Hello, PrintStream!");ps.printf("Formatted number: %.2f", 123.456);} catch (IOException e) {e.printStackTrace();}}
}
import java.io.PrintWriter;
import java.io.FileWriter;
import java.io.IOException;public class PrintWriterExample {public static void main(String[] args) {try (PrintWriter pw = new PrintWriter(new FileWriter("printWriter.txt"))) {pw.println("Hello, PrintWriter!");pw.printf("Formatted text: %s", "Java IO");} catch (IOException e) {e.printStackTrace();}}
}
4. 装饰者模式(Decorator Pattern)
在 Java 语言中,装饰者模式(Decorator Pattern) 是一种结构型设计模式,它允许动态地为对象添加新功能,而不改变其原始结构。在 Java 的 IO(输入/输出)系统中,装饰者模式被广泛应用,例如 BufferedReader 便是 Reader 的装饰者。
4.1. 装饰者模式概述
装饰者模式的特点
-
增强功能:在不修改原有类的情况下,动态添加新功能。
-
符合开闭原则(OCP):对扩展开放,对修改封闭。
-
支持递归组合:装饰者可以装饰另一个装饰者,实现更复杂的功能。
典型应用场景
-
Java IO(
BufferedReader装饰FileReader提高效率)。 -
图形界面(
BorderDecorator装饰Window以增加边框)。 -
数据加密(
DataStream装饰FileStream以增加加密功能)。
4.2 代码示例:基于装饰者模式的 Reader 设计
在 Decorator_pattern 目录下,我们设计了一组 Reader_ 类,它们模仿 Java IO 中的 Reader,并通过装饰者模式扩展其功能。
Reader_(抽象基类)
//作用://Reader_ 是抽象基类,定义了 read() 和 readLine() 方法。//允许子类继承,实现具体的读取方式。import java.io.Reader;
import java.io.IOException;abstract class Reader_ {protected Reader reader;public Reader_(Reader reader) {this.reader = reader;}public abstract int read() throws IOException;public abstract String readLine() throws IOException;public void close() throws IOException {reader.close();}
}
File_reader_(从文件读取数据)
//作用:
//
//直接从文件读取字符。//不支持 readLine(),需要 BufferedReader 进行封装。import java.io.FileReader;
import java.io.IOException;class File_reader_ extends Reader_ {public File_reader_(String filePath) throws IOException {super(new FileReader(filePath));}@Overridepublic int read() throws IOException {return reader.read();}@Overridepublic String readLine() throws IOException {throw new UnsupportedOperationException("FileReader 不支持 readLine");}
}
Buffered_reader_(增强 File_reader_,增加缓冲)
//作用://BufferedReader 的封装,提供 readLine() 方法。//装饰 File_reader_,增强其功能。class Buffered_reader_ extends Reader_ {private BufferedReader bufferedReader;public Buffered_reader_(Reader_ reader) {super(reader.reader);this.bufferedReader = new BufferedReader(reader);}@Overridepublic int read() throws IOException {return bufferedReader.read();}@Overridepublic String readLine() throws IOException {return bufferedReader.readLine();}
}
String_reader_(从字符串读取数据)
//作用://直接从 String 读取数据,而不是文件。
import java.io.StringReader;
import java.io.IOException;class String_reader_ extends Reader_ {public String_reader_(String data) {super(new StringReader(data));}@Overridepublic int read() throws IOException {return reader.read();}@Overridepublic String readLine() throws IOException {throw new UnsupportedOperationException("StringReader 不支持 readLine");}
}
Test(测试代码)
import java.io.IOException;public class Test {public static void main(String[] args) {try {System.out.println("读取文件示例:");Reader_ fileReader = new File_reader_("example.txt");Reader_ bufferedReader = new Buffered_reader_(fileReader);String line;while ((line = bufferedReader.readLine()) != null) {System.out.println(line);}bufferedReader.close();System.out.println("\n读取字符串示例:");Reader_ stringReader = new String_reader_("Hello, World!");int ch;while ((ch = stringReader.read()) != -1) {System.out.print((char) ch);}stringReader.close();} catch (IOException e) {e.printStackTrace();}}
}
4.3 小结
通过装饰者模式,我们可以 灵活组合不同的 Reader_ 类,增强功能。
5. IO 流的应用场景
5.1 文件操作
-
读取、写入、复制、删除文件。
-
示例:日志文件处理、配置文件读取。
5.2 网络通信
-
通过
Socket实现客户端和服务器之间的数据传输。 -
示例:文件传输、实时聊天。
5.3 数据处理
-
解析 CSV、JSON 等格式的数据。
-
示例:数据导入导出、数据分析。
6. IO 流的最佳实践
6.1 使用缓冲流
-
缓冲流(如
BufferedReader、BufferedInputStream)可以显著提高 IO 性能。
6.2 使用 try-with-resources
-
确保流在使用后自动关闭,避免资源泄漏。
6.3 处理大文件
-
对于大文件,使用分块读写(如
byte[] buffer)避免内存溢出。
7. 总结
Java IO 流是处理数据输入输出的核心工具,涵盖了字节流、字符流、缓冲流等多种类型。通过经典代码实例和最佳实践,本文帮助你全面掌握 IO 流的使用方法。无论是文件操作、网络通信,还是数据处理,IO 流都能为你提供强大的支持。
相关文章:
Java IO 流:从字节到字符再到Java 装饰者模式(Decorator Pattern),解析与应用掌握数据流动的艺术
在 Java 编程中,IO(输入输出)流是处理数据输入输出的核心工具。无论是读取文件、网络通信,还是处理用户输入,IO 流都扮演着重要角色。本文将深入探讨 Java IO 流的核心概念、分类、经典代码实例及其应用场景࿰…...
爬虫案例-爬取某站视频
文章目录 1、下载FFmpeg2、爬取代码3、效果图 1、下载FFmpeg FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。 点击下载: ffmpeg 安装并配置 FFmpeg 步骤: 1.下载 FFmpeg: 2.访问 FFmpeg 官网。 3.选择 Wi…...
nacos-未经授权创建用户漏洞
1、修改配置文件 vim application.properties# 修改配置项 nacos.core.auth.enabledtrue nacos.core.auth.enable.userAgentAuthWhitefalse2、重启nacos systemctl restart nacos3、验证 打开nacos部署服务器输入命令 curl -XPOST -d “usernametest123&passwordtest!123…...
C++:IO库
一、C IO库的架构 C标准库中的IO系统基于流(Stream)的概念,分为三层结构: 流对象(如cin, cout, fstream)流缓冲区(streambuf,负责底层数据处理)数据源/目的…...
企业级前端架构设计与实战
一、架构设计核心原则 1.1 模块化分层架构 典型目录结构: src/├── assets/ # 静态资源├── components/ # 通用组件├── pages/ # 页面模块├── services/ # API服务层├── store/ # 全局状态管理├── uti…...
从入门到精通【MySQL】 CRUD
文章目录 📕1. Create 新增✏️1.1 单行数据全列插入✏️1.2 单行数据指定列插入✏️1.3 多行数据指定列插入 📕2. Retrieve 检索✏️2.1 全列查询✏️2.2 指定列查询✏️2.3 查询字段为表达式✏️2.4 为查询结果指定别名✏️2.5 结果去重查询 …...
08_双向循环神经网络
双向网络 概念 双向循环神经网络(Bidirectional Recurrent Neural Network, BiRNN)通过同时捕捉序列的正向和反向依赖关系,增强模型对上下文的理解能力。与传统的单向网络不同,BIRNN 能够同时从过去和未来的上下文信息中学习,从而提升模型的…...
JSON数据修改的实现
JSON数据的修改 示例代码如下: using System.Collections; using System.Collections.Generic; using UnityEngine; //C#命名空间(以System开头) using System.IO; using LitJson; public class JsonChange : MonoBehaviour {// Start is called befor…...
2025年Postman的五大替代工具
虽然Postman是一个广泛使用的API测试工具,但许多用户在使用过程中会遇到各种限制和不便。因此,可能需要探索替代解决方案。本文介绍了10款强大的替代工具,它们能够有效替代Postman,成为你API测试工具箱的一部分。 什么是Postman&…...
(四)---四元数的基础知识-(定义)-(乘法)-(逆)-(退化到二维复平面)-(四元数乘法的导数)
使用四元数的原因 最重要的原因是因为传感器的角速度计得到的是三个轴的角速度, 这三个轴的角速度合成一个角速度矢量, 结果就是在微小时间内绕着这个角速度矢量方向为轴旋转一定角度. 截图来源网址四元数 | Crazepony开源四轴飞行器...
汇能感知高品质的多光谱相机VSC02UA
VSC02UA概要 VSC02UA是一款高品质的200万像素的光谱相机,适用于工业检测、农业、医疗等领域。VSC02UA 包含 1600 行1200 列有源像素阵列、片上 10 位 ADC 和图像信号处理器。它带有 USB2.0 接口,配合专门的电脑上位机软件使用,可进行图像采集…...
【SpringBoot】MorningBox小程序的完整后端接口文档
以下是「晨光宅配」小程序的完整接口文档,涵盖了所有12个表的接口。 每个接口包括请求方法、URL、请求参数、响应格式和示例 接口文档 1. 用户模块 1.1 获取用户信息 URL: /user/{userId}方法: GET请求参数: userId (路径参数): 用户ID响应格式:{"userId": 1,&qu…...
Blazor+PWA技术打造全平台音乐播放器-从音频缓存到离线播放的实践之路
开局三张图… 0.起源 主要是自己现在用的是苹果手机,虽然手机很高级,但是想听自己喜欢的歌曲确是不容易,在线app都要付费,免费的本地播放器都不太好用(收费的也不太行),基础功能都不满足。此外…...
使用LangChain开发智能问答系统
代码地址见文末 1. 项目配置 1.1 Neo4j 数据库配置 1. 安装与环境变量 解压路径:将neo4j-community-5.x.x.zip解压至D:\neo4j-community-5.x.x环境变量: NEO4J_HOME: D:\neo4j-community-5.x.xJAVA_HOME: D:\neo4j-community-5.x.x\jdk(注意:需指向 JDK 目录)Path 变量…...
Centos操作系统安装及优化
Centos操作系统安装及优化 零、环境概述 主机名 centos版本 cpu 内存 Vmware版本 ip地址 test CentOS Linux release 7.6.1810 (Core) 2C 2G 15.5.1 10.0.0.10 一、介质下载 1、7.6版本下载 CentOS7.6标准版下载链接: https://archive.kernel.org/centos-vault/7.6.1810/i…...
游戏引擎学习第177天
仓库:https://gitee.com/mrxiao_com/2d_game_4 今日计划 调试代码有时可能会非常困难,尤其是在面对那些难以发现的 bug 时。显然,调试工具是其中一个非常重要的工具,但在游戏开发中,另一个非常常见的工具就是自定义的调试工具&a…...
springCloud集成tdengine(原生和mapper方式) 其一
第一种 mapper方式,原生方式在主页看第二章 一、添加pom文件 <!-- HikariCP 连接池 --><dependency><groupId>com.zaxxer</groupId><artifactId>HikariCP</artifactId></dependency><!-- TDengine 连接器--><de…...
数据结构知识点1
目录 一、时间复杂度和空间复杂度 1.1时间复杂度: 1.2空间复杂度: 二、装箱和拆箱 三、泛型 3.1泛型类的使用: 3.2泛型的上界: 3.3泛型方法: 一、时间复杂度和空间复杂度 1.1时间复杂度: 时间复杂…...
时序数据库QuestDB在Winform窗体应用
以下是QuestDB在Winform使用的代码: //初始化 private void Init() { //创建数据库对象 (用法和EF Dappper一样通过new保证线程安全) SqlSugarClient Db new SqlSugarClient(new ConnectionConfig() { ConnectionString “host10.3.5.227;port8812;usernameadmin;…...
从零开始学习 Go 语言
Go 语言(又称 Golang)是由 Google 开发的一种静态强类型、编译型、并发型编程语言。它以其简洁的语法、高效的并发支持和强大的标准库而闻名,非常适合开发高性能的服务器端应用、分布式系统和云计算工具。本文将从零开始,详细介绍…...
自由学习记录(45)
顶点片元着色器(important) 1.需要在Pass渲染通道中编写着色器逻辑 2.可以使用cG或HLSL两种shader语言去编写Shader逻辑 3.代码量较多,灵活性较强,性能消耗更可控,可以实现更多渲染细节 4.适用于光照处理较少…...
数据源支持远程Excel/CSV,数据集支持分组字段功能,DataEase开源BI工具v2.10.6 LTS版本发布
2025年3月17日,人人可用的开源BI工具DataEase正式发布v2.10.6 LTS版本。 这一版本的功能变动包括:数据源方面,新增支持远程Excel/CSV数据源,支持以HTTP、HTTPS、FTP协议获取远程服务器上的Excel和CSV数据文件,并且可以…...
SpringBoot3使用CompletableFuture时java.util.ConcurrentModificationException异常解决方案
问题描述 在Spring Boot 3项目中,使用CompletableFuture进行异步编程时,偶发{"code":500,"msg":"java.util.ConcurrentModificationException"}异常,但代码中并未直接操作List或CopyOnWriteArrayList等集合类…...
【Nodejs】2024 汇总现状
之前已经调研了容器、nexus-public,实现了本地构建应用镜像和基础设施的镜像。为实现分布式一体化协作开发的目标,还需要配套的线上协作开发环境。故而重回前端调研现状,比较 5 年前的 nodejs 快好的啊。 以下是针对 Node.js 工具链的深度解析…...
LeetCode 每日一题 2025/3/17-2025/3/23
记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步 目录 3/17 1963. 使字符串平衡的最小交换次数3/18 2614. 对角线上的质数3/19 2610. 转换二维数组3/20 2612. 最少翻转操作数3/21 2680. 最大或值3/22 2643. 一最多的行3/23 2116…...
STM32__红外避障模块的使用
目录 一、红外避障模块 概述 二、直接读取OUT引脚电平 三、使用中断方式触发 一、红外避障模块 概述 引脚解释: VCC接3.3V 或 5.0VGND接开发板的GNDOUT数字量输出(0或1); 低电平时表示前方有障碍 ; 通过可调电阻调整检测距离 产品特点: …...
android 音量调节
安卓音频数据的最终音量由三部分组成,分别是master volume(全局音量,对整个系统所有的音频数据生效),stream volume(流音量,只针对特定类型的音频数据生效)和track volume(track音量,只针对某个audiotrack的…...
Redis JSON 用id读取content总结(sendCommand())
Redis JSON 读取总结(方法 2 - sendCommand()) 💡 背景 在 Redis 中,我们存储了 JSON 数据,并希望通过 Jedis sendCommand() 方式读取 JSON 里的 "content" 字段。由于 jedis.jsonGet() 可能在旧版本不支持…...
使用Qdrant等其他向量数据库时需要将将numpy 数组转换为列表 确保数据能被正确处理和序列化,避免类型不兼容的问题。
在使用Qdrant等其他向量数据库时需要 转换 numpy 数组为列表主要是为了确保数据能被正确处理和序列化,避免类型不兼容的问题。具体原因如下: 序列化兼容性: 很多数据库接口、API 或者 JSON 序列化工具只能处理 Python 的内置类型(…...
[AI速读]如何构建高效的AMBA协议检查器(Checker IP)
在芯片验证过程中,检查器(Checker)是确保设计符合协议规范的关键工具。本文基于一篇技术论文,分享如何为AMBA协议(如AXI、AHB)构建可重用的检查器IP(Checker IP,简称CIP),并简化其核心思路,帮助工程师快速上手。 一、什么是Checker IP? Checker IP是一组用SystemVe…...
