Java-IO流之打印流详解
Java-IO流之打印流详解
- 一、打印流概述
- 1.1 什么是打印流
- 1.2 打印流的特点
- 1.3 打印流的应用场景
- 二、PrintStream详解
- 2.1 基本概念
- 2.2 构造函数
- 2.3 核心方法
- 2.4 使用示例
- 三、PrintWriter详解
- 3.1 基本概念
- 3.2 构造函数
- 3.3 核心方法
- 3.4 使用示例
- 四、PrintStream与PrintWriter的比较
- 4.1 相同点
- 4.2 不同点
- 4.3 如何选择
- 五、打印流的高级应用
- 5.1 重定向标准输出
- 5.2 自定义打印流
- 5.3 日志记录系统
- 六、打印流的最佳实践
- 6.1 始终启用自动刷新
- 6.2 使用try-with-resources语句
- 6.3 处理大文件时使用缓冲
- 6.4 正确处理字符编码
- 七、常见问题与解决方案
- 7.1 输出内容未显示
- 7.2 中文乱码问题
- 7.3 性能问题
- 7.4 错误处理
Java中打印流(Print Stream)是一种特殊的输出流,它提供了方便的打印方法,PrintStream
和PrintWriter
分别适用于字节流和字符流的场景,提供了丰富的打印方法和自动刷新功能,使数据输出变得简单直观。本文我将深入探讨Java打印流的原理、使用方法及高级应用,帮你全面掌握这一实用技术。
一、打印流概述
1.1 什么是打印流
打印流是Java IO体系中用于格式化输出的流,它提供了一系列重载的print()
和println()
方法,可以方便地输出各种数据类型。Java提供了两种打印流:
- PrintStream:字节打印流,处理字节数据
- PrintWriter:字符打印流,处理字符数据
1.2 打印流的特点
- 自动刷新:可以在输出换行符或字节数组后自动刷新缓冲区
- 不抛出IOException:打印流的方法不会抛出IOException,而是设置一个内部错误标志
- 格式化输出:提供了格式化输出的方法,如
printf()
- 支持多种数据类型:可以直接打印各种基本数据类型和对象
1.3 打印流的应用场景
- 控制台输出:System.out和System.err就是PrintStream实例
- 日志记录:将程序运行信息输出到日志文件
- 数据导出:将数据以格式化的方式输出到文件或网络
- 调试信息输出:在开发过程中输出调试信息
二、PrintStream详解
2.1 基本概念
PrintStream
是一个字节打印流,继承自FilterOutputStream
,可以接受任何OutputStream作为底层输出流。
2.2 构造函数
PrintStream(OutputStream out)
:创建一个不带自动刷新的PrintStreamPrintStream(OutputStream out, boolean autoFlush)
:创建一个带自动刷新的PrintStreamPrintStream(OutputStream out, boolean autoFlush, String encoding)
:创建一个带指定字符编码和自动刷新的PrintStreamPrintStream(String fileName)
:创建一个输出到指定文件的PrintStreamPrintStream(File file)
:创建一个输出到指定File对象的PrintStream
2.3 核心方法
print()
:打印各种数据类型println()
:打印各种数据类型并换行printf()
:格式化输出format()
:格式化输出,功能与printf()相同append()
:追加字符序列flush()
:刷新流close()
:关闭流
2.4 使用示例
import java.io.*;public class PrintStreamExample {public static void main(String[] args) {try (PrintStream ps = new PrintStream(new FileOutputStream("output.txt"), true, "UTF-8")) {// 打印基本数据类型ps.println("Hello, PrintStream!");ps.println(42);ps.println(3.14159);ps.println(true);// 打印对象ps.println(new java.util.Date());// 格式化输出ps.printf("姓名: %s, 年龄: %d%n", "张三", 30);// 追加内容ps.append("这是追加的内容\n");} catch (IOException e) {e.printStackTrace();}}
}
三、PrintWriter详解
3.1 基本概念
PrintWriter
是一个字符打印流,继承自Writer
,提供了与PrintStream
类似的API,但专门处理字符数据。
3.2 构造函数
PrintWriter(Writer out)
:创建一个不带自动刷新的PrintWriterPrintWriter(Writer out, boolean autoFlush)
:创建一个带自动刷新的PrintWriterPrintWriter(OutputStream out)
:从OutputStream创建一个不带自动刷新的PrintWriterPrintWriter(OutputStream out, boolean autoFlush)
:从OutputStream创建一个带自动刷新的PrintWriterPrintWriter(String fileName)
:创建一个输出到指定文件的PrintWriterPrintWriter(File file)
:创建一个输出到指定File对象的PrintWriterPrintWriter(String fileName, String csn)
:创建一个带指定字符编码的PrintWriter
3.3 核心方法
PrintWriter
的方法与PrintStream
类似,包括:
print()
println()
printf()
format()
append()
flush()
close()
3.4 使用示例
import java.io.*;public class PrintWriterExample {public static void main(String[] args) {try (PrintWriter pw = new PrintWriter(new FileWriter("output.txt"), true)) {// 打印基本数据类型pw.println("Hello, PrintWriter!");pw.println(123);pw.println(3.14);pw.println(false);// 打印对象pw.println(new java.util.Date());// 格式化输出pw.printf("金额: %.2f 元%n", 1234.567);// 追加内容pw.append("这是使用PrintWriter追加的内容\n");} catch (IOException e) {e.printStackTrace();}}
}
四、PrintStream与PrintWriter的比较
4.1 相同点
- 都提供了print()、println()、printf()等方法
- 都可以自动刷新缓冲区
- 都不会抛出IOException
4.2 不同点
特性 | PrintStream | PrintWriter |
---|---|---|
继承关系 | 继承自FilterOutputStream | 继承自Writer |
处理数据类型 | 字节流 | 字符流 |
自动刷新条件 | 输出换行符(\n)或调用println() | 输出换行符(\n)或调用println()或print() |
字符编码支持 | 需要在构造函数中指定 | 可以通过OutputStreamWriter指定 |
适用场景 | 输出字节数据,如文件、网络 | 输出文本数据,如文本文件 |
4.3 如何选择
- 如果需要处理字节数据(如二进制文件),使用
PrintStream
- 如果需要处理字符数据(如文本文件),使用
PrintWriter
- 在需要国际化支持的场景中,优先使用
PrintWriter
- 在处理控制台输出时,两者均可使用,但
PrintWriter
更适合处理字符编码问题
五、打印流的高级应用
5.1 重定向标准输出
可以通过System.setOut()
和System.setErr()
方法重定向标准输出和错误输出:
import java.io.*;public class RedirectStandardOutput {public static void main(String[] args) {try {// 保存原始的标准输出PrintStream originalOut = System.out;// 重定向标准输出到文件PrintStream fileOut = new PrintStream(new FileOutputStream("log.txt"));System.setOut(fileOut);// 现在所有的System.out.println()都会输出到文件System.out.println("这是输出到文件的内容");// 恢复标准输出System.setOut(originalOut);System.out.println("这是输出到控制台的内容");// 关闭文件输出流fileOut.close();} catch (IOException e) {e.printStackTrace();}}
}
5.2 自定义打印流
可以通过继承PrintStream
或PrintWriter
来创建自定义打印流:
import java.io.*;public class CustomPrintStream extends PrintStream {private int lineCount = 0;public CustomPrintStream(OutputStream out) {super(out, true);}@Overridepublic void println(String x) {lineCount++;super.println("[" + lineCount + "] " + x);}public int getLineCount() {return lineCount;}public static void main(String[] args) {try (CustomPrintStream cps = new CustomPrintStream(new FileOutputStream("custom_output.txt"))) {cps.println("第一行");cps.println("第二行");cps.println("第三行");System.out.println("总共输出了 " + cps.getLineCount() + " 行");} catch (IOException e) {e.printStackTrace();}}
}
5.3 日志记录系统
打印流非常适合实现简单的日志记录系统:
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;public class Logger {private static PrintWriter writer;private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");static {try {// 创建日志文件,以当前日期命名String fileName = "log_" + DATE_FORMAT.format(new Date()).replace(":", "-") + ".txt";writer = new PrintWriter(new FileWriter(fileName, true), true);} catch (IOException e) {e.printStackTrace();}}public static void log(String message) {String logEntry = "[" + DATE_FORMAT.format(new Date()) + "] " + message;writer.println(logEntry);System.out.println(logEntry); // 同时输出到控制台}public static void error(String message) {log("[ERROR] " + message);}public static void warn(String message) {log("[WARN] " + message);}public static void info(String message) {log("[INFO] " + message);}public static void close() {if (writer != null) {writer.close();}}public static void main(String[] args) {Logger.info("程序启动");try {// 模拟业务逻辑Thread.sleep(1000);Logger.info("业务逻辑执行中");// 模拟错误throw new RuntimeException("模拟异常");} catch (Exception e) {Logger.error("发生异常: " + e.getMessage());}Logger.info("程序结束");Logger.close();}
}
六、打印流的最佳实践
6.1 始终启用自动刷新
在创建打印流时,建议启用自动刷新功能,确保数据及时输出:
// 启用自动刷新的PrintWriter
PrintWriter pw = new PrintWriter(new FileWriter("output.txt"), true);// 启用自动刷新的PrintStream
PrintStream ps = new PrintStream(new FileOutputStream("output.txt"), true);
6.2 使用try-with-resources语句
确保打印流资源被正确关闭,避免资源泄漏:
try (PrintWriter writer = new PrintWriter(new FileWriter("output.txt"))) {// 使用打印流
} catch (IOException e) {e.printStackTrace();
}
6.3 处理大文件时使用缓冲
在处理大文件输出时,结合使用缓冲流可以提高性能:
try (PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter("large_output.txt")))) {// 处理大量输出for (int i = 0; i < 100000; i++) {writer.println("Line " + i);}
} catch (IOException e) {e.printStackTrace();
}
6.4 正确处理字符编码
在需要处理不同字符编码的场景中,确保正确设置字符编码:
// 使用指定编码的PrintWriter
try (PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream("output.txt"), "UTF-8"))) {writer.println("中文测试");
} catch (IOException e) {e.printStackTrace();
}
七、常见问题与解决方案
7.1 输出内容未显示
可能是因为没有启用自动刷新,并且没有调用flush()
方法。解决方案是启用自动刷新或手动调用flush()
。
7.2 中文乱码问题
可能是因为字符编码不匹配。解决方案是确保在创建打印流时指定正确的字符编码,例如:
PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream("output.txt"), "UTF-8"));
7.3 性能问题
在处理大量输出时,频繁的IO操作可能导致性能问题。解决方案是结合使用缓冲流:
PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter("large_output.txt")));
7.4 错误处理
打印流的方法不会抛出IOException,但可以通过checkError()
方法检查是否发生错误:
PrintWriter writer = new PrintWriter(new FileWriter("output.txt"));
writer.println("Hello");if (writer.checkError()) {System.out.println("发生错误");
}
若这篇内容帮到你,动动手指支持下!关注不迷路,干货持续输出!
ヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノ
相关文章:
Java-IO流之打印流详解
Java-IO流之打印流详解 一、打印流概述1.1 什么是打印流1.2 打印流的特点1.3 打印流的应用场景 二、PrintStream详解2.1 基本概念2.2 构造函数2.3 核心方法2.4 使用示例 三、PrintWriter详解3.1 基本概念3.2 构造函数3.3 核心方法3.4 使用示例 四、PrintStream与PrintWriter的比…...
高效图像处理:使用 Pillow 进行格式转换与优化
高效图像处理:使用 Pillow 进行格式转换与优化 1. 背景引入 在图像处理应用中,格式转换、裁剪、压缩等操作是常见需求。Python 的 Pillow 库基于 PIL(Python Imaging Library),提供 轻量、强大 的图像处理能力,广泛用于 Web 开发、数据分析、机器学习 等领域。 本文将…...
Github 2025-06-06 Java开源项目日报Top10
根据Github Trendings的统计,今日(2025-06-06统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Java项目10TypeScript项目1Java实现的算法集合:使用Gitpod.io进行编辑和贡献 创建周期:2883 天开发语言:Java协议类型:MIT LicenseStar数量…...
使用 Ansible 在 Windows 服务器上安装 SSL 证书
在本教程中,我将向您展示如何使用 Ansible 在 Windows 服务器上安装 SSL 证书。使用 Ansible 自动化 SSL 证书安装过程可以提高 IT 运营的效率、一致性和协作性。我将介绍以下步骤: 将 SSL 证书文件复制到服务器将 PFX 证书导入指定的存储区获取导入的证…...
厂区能源监控系统:网关赋能下的高效能源管理与环保监测
在现代工业生产领域,能源的有效利用与环境保护是企业实现可持续发展的两大关键要素。厂区能源监控系统借助先进的信息技术与自动化控制手段,对厂区内能源消耗及污水处理等核心环节展开实时监控与精细化管理。其中,御控网关作为系统关键枢纽&a…...
CentOS 7 如何安装llvm-project-10.0.0?
CentOS 7 如何安装llvm-project-10.0.0? 需要先升级gcc至7.5版本,详见CentOS 7如何编译安装升级gcc版本?一文 # 备份之前的yum .repo文件至 /tmp/repo_bak 目录 mkdir -p /tmp/repo_bak && cd /etc/yum.repo.d && /bin/mv ./*.repo …...
Cursor 1.0 的核心功能亮点及技术价值分析
Cursor 1.0 的核心功能亮点及技术价值分析 结合官方更新和开发者实测整理: 🛠️ 一、BugBot:智能自动化代码审查 功能亮点:深度集成 GitHub,自动扫描 Pull Request(PR)中的潜在 Bug(…...
软考 系统架构设计师系列知识点之杂项集萃(83)
接前一篇文章:软考 系统架构设计师系列知识点之杂项集萃(82) 第150题 体系结构权衡分析方法(Architecture Tradeoff Analysis Method,ATAM)是一种常见的系统架构评估框架,该框架主要关注系统的…...

NLP学习路线图(二十六):自注意力机制
一、为何需要你?序列建模的困境 在你出现之前,循环神经网络(RNN)及其变种LSTM、GRU是处理序列数据(如文本、语音、时间序列)的主流工具。它们按顺序逐个处理输入元素,将历史信息压缩在一个隐藏…...

Unity3D仿星露谷物语开发60之定制角色其他部位
1、目标 上一篇中定制了角色的衬衫、手臂。 本篇中将定制角色其他部位的图形,包括:裤子、发型、皮肤、帽子等。 2、定制裤子 (1)修改ApplyCharacterCustomisation.cs脚本 我们需要设置一个输入框选择裤子的颜色。 // Select …...
C++动态链接库封装,供C#/C++ 等编程语言使用——C++动态链接库概述(总)
目录: 一、前言及背景1.1需求描述1.2常见编程语言对比1.3应用背景 二、C对外接口2.1C对外封装2.2基于目标平台封装接口形式 三、系列文章汇总 一、前言及背景 1.1需求描述 不同的编程语言,具有不同的编程生态环境,对于项目应用来说ÿ…...

Google机器学习实践指南(机器学习模型泛化能力)
🔥 Google机器学习(14)-机器学习模型泛化能力解析 Google机器学习(14)-机器学习模型泛化原理与优化(约10分钟) 一、泛化问题引入 ▲ 模型表现对比: 假设森林中树木健康状况预测模型: 图1:初始模型表现 …...

MySQL性能调优:Mysql8高频面试题汇总
1,主键和唯一键有什么区别? 主键不能重复,不能为空,唯一键不能重复,可以为空。 建立主键的目的是让外键来引用。 一个表最多只有一个主键,但可以有很多唯一键 2,MySQL常用的存储引擎有哪些&…...
Neo4j 数据建模:原理、技术与实践指南
Neo4j 作为领先的图数据库,其核心优势在于利用图结构直观地表达和高效地查询复杂关系。其数据建模理念与传统关系型数据库截然不同,专注于实体(节点)及其连接(关系)。以下基于官方文档,系统阐述其建模原理、关键技术、实用技巧及最佳实践: 一、 核心原理:以关系为中心…...
【数据结构知识分享】顺序表详解
一、存储结构 物理相邻性: 若元素 a 和 b 逻辑相邻,则它们在内存中的地址也连续(如 &a[i1] &a[i] sizeof(ElemType))。 内存布局x: 基地址 索引 元素大小,通过首地址直接计算任意位置地址。 …...

vue+elementUI+springboot实现文件合并前端展示文件类型
项目场景: element的table上传文件并渲染出文件名称点击所属行可以查看文件,并且可以导出合并文件,此文章是记录合并文档前端展示的帖子 解决方案: 后端定义三个工具类 分别是pdf,doc和word的excle的目前我没整 word的工具类 package com.sc.modules…...

高效绘制业务流程图!专业模板免费下载
在复杂的业务流程管理中,可视化工具已成为提升效能的核心基础设施。为助力开发者、项目经理及业务架构师高效落地流程标准化,本文将为你精选5套开箱即用的专业流程图模板。这些模板覆盖跨部门协作、电商订单、客户服务等高频场景,具备以下核心…...

Spring Boot + Prometheus 实现应用监控(基于 Actuator 和 Micrometer)
文章目录 Spring Boot Prometheus 实现应用监控(基于 Actuator 和 Micrometer)环境准备示例结构启动和验证验证 Spring Boot 应用Prometheus 抓取配置(静态方式)Grafana 面板配置总结 Spring Boot Prometheus 实现应用监控&…...

PowerBI企业运营分析—列互换式中国式报表分析
PowerBI企业运营分析—列互换式中国式报表分析 欢迎来到Powerbi小课堂,在竞争激烈的市场环境中,企业运营分析平台成为提升竞争力的核心工具。 该平台通过高效整合多源数据,并实时监控关键指标,能够迅速揭示业务表现的全貌&#…...

BugKu Web渗透之需要管理员
启动场景,打开网页,显示如下: 一般没有上面头绪的时候,就是两步:右键查看源代码 和 扫描网站目录。 步骤一: 右键查看源代码 和 扫描网站目录。 右键查看源代码没有发现异常。 于是扫描网站目录&…...
Java集合初始化:Lists.newArrayList vs new ArrayList()
文章目录 前言一、核心区别全景图二、代码实现深度对比1. 初始化方式对比2. 容量预分配机制 三、性能与底层原理1. 内存分配策略2. 基准测试数据(JMH) 四、Guava的进阶功能生态1. 集合转换2. 集合分片3. 不可变集合创建 五、最佳实践指南六、源码级实现解…...
VBA清空数据
列数转字母 Function CNtoW(ByVal num As Long) As String CNtoW Replace(Cells(1, num).Address(False, False), "1", "") End Function 字母转列数 Function CWtoN(ByVal AB As String) As Long CWtoN Range("a1:" & AB & &…...
【信息系统项目管理师-选择真题】2025上半年(第二批)综合知识答案和详解(回忆版)
更多内容请见: 备考信息系统项目管理师-专栏介绍和目录 文章目录 【第1题】【第2题】【第3题】【第4题】【第5题】【第6题】【第7题】【第8题】【第9题】【第10题】【第11题】【第12题】【第13题】【第14题】【第15题】【第16题】【第17题】【第18题】【第19题】【第20题】【第…...
Java Lambda 表达式的缺点和替代方案
Java 8 引入的 Lambda 表达式曾被誉为编写简洁、函数式代码的革命性工具。但说实话,它们并不是万能钥匙。它有不少问题,比如它没有宣传的那么易读,在某些场景下还带来性能开销。 作为一名多年与 Java 冗长语法搏斗的开发者,我找到了更注重清晰、可维护性和性能的替代方案。…...

TDengine 开发指南—— UDF函数
UDF 简介 在某些应用场景中,应用逻辑需要的查询功能无法直接使用内置函数来实现,TDengine 允许编写用户自定义函数(UDF),以便解决特殊应用场景中的使用需求。UDF 在集群中注册成功后,可以像系统内置函数一…...

使用vsftpd搭建FTP服务器(TLS/SSL显式加密)
安装vsftpd服务 使用vsftpd RPM安装包安装即可,如果可以访问YUM镜像源,通过dnf或者yum工具更加方便。 yum -y install vsftpd 启动vsftpd、查看服务状态 systemctl enable vsftpd systemctl start vsftpd systemctl status vsftpd 备份配置文件并进…...

1.1Nodejs和浏览器中的二进制处理
Buffer 在 Node.js 中,Buffer 类用于处理二进制数据。由于 JavaScript 在浏览器环境中主要用于处理字符串和数字等类型的数据,对二进制数据的处理能力较弱,因此 Node.js 引入了 Buffer 类来弥补这一不足,特别是在处理文件系统操作…...

入门AJAX——XMLHttpRequest(Post)
一、前言 在上篇文章中,我们已经介绍了 HMLHttpRequest 的GET 请求的基本用法,并基于我提供的接口练习了两个简单的例子。如果你还没有看过第一篇文章,强烈建议你在学习完上篇文章后再学习本篇文章: 🔗入门AJAX——XM…...

Qt(part1)Qpushbutton,信号与槽,对象树,自定义信号与槽,lamda表达式。
1、创建Qt程序 2、命名规范及快捷键 3、Qpushbutton按钮创建 4、对象树概念 5、信号与槽 6、自定义信号与槽 7、当自定义信号和槽发生重载时 8、信号可以连接信号,信号也可以断开。 9、lamda表达式...

西北某省级联通公司:3D动环模块如何实现机房“一屏统管”?
一、运营商机房监控痛点凸显 在通信行业快速发展的当下,西北某省级联通公司肩负着保障区域通信畅通的重任。然而,公司分布广泛的机房面临着诸多监控难题,尤其是偏远机房环境风险无法实时感知这一痛点,严重影响了机房的稳定运行和通…...