Java IO: PrintStream 类

Java 的 PrintStream 类(即 java.io.PrintStream)能够让你将格式化的数据写入底层的 OutputStream。该类具备将 int、long 等基本数据类型转化为文本形式的能力,而非直接处理它们的字节值。这也正是它被命名为 PrintStream 的缘由,它会把原始数据转化为文本,就如同信息被打印到屏幕上(或是打印在纸张上)时呈现的样子。

PrintStream 示例

以下是一个简单的 PrintStream 示例:

package com.hxstrive.java_io;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintStream;

public class PrintStreamExample {
    public static void main(String[] args) throws IOException {
        // 写出数据
        try(PrintStream ps = new PrintStream("test.txt")){
            ps.println("Hello, Java!");
            ps.println((int)1024);
            ps.println(true);
            ps.println(3.1415d);
        }

        // 读取数据
        try(BufferedInputStream in = new BufferedInputStream(new FileInputStream("test.txt"))) {
            byte[] buffer = new byte[1024];
            int len = in.read(buffer);
            System.out.println(new String(buffer, 0, len));
        }
    }
}

运行输出:

Hello, Java!
1024
true
3.1415

上述示例,首先创建了一个连接到 OutputStream 的 PrintStream。其次,向 PrintStream 打印几个原始值,写入到 test.txt 文件。最后,通过 BufferedInputStream 读取 test.txt 文件的内容。

System.out 和 System.err 是 PrintStream

你或许对 Java 里两个广为人知的 PrintStream 实例并不陌生,它们就是 System.out 和 System.err。倘若你曾使用过这两个流中的任意一个,那实际上你就已经用过 PrintStream 了。

printf()

在 Java 中,PrintStream 类提供了功能强大的 format() 和 printf() 方法。这两个方法的功能是完全一致的,不过对于熟悉 C 语言的程序员而言,“printf” 这个名称会让他们感觉更为亲切。借助这些方法,你能够运用格式化字符串,以一种十分高级的方式将文本和数据进行融合。

示例:

package com.hxstrive.java_io;

import java.io.PrintStream;

public class PrintStreamPrintfExample {
    public static void main(String[] args) {
        // 定义一些不同类型的变量,用于后续格式化输出
        String name = "Alice";
        int age = 25;
        double height = 1.65;
        boolean isStudent = true;

        try(PrintStream ps = System.out) {
            // 输出基本信息,使用 %s 格式化字符串,%d 格式化整数
            ps.printf("姓名: %s,年龄: %d 岁\n", name, age);

            // 输出带有小数的信息,使用 %.2f 格式化双精度浮点数,保留两位小数
            ps.printf("姓名: %s,身高: %.2f 米\n", name, height);

            // 输出布尔值信息,使用 %b 格式化布尔值
            ps.printf("姓名: %s,是否为学生: %b\n", name, isStudent);

            // 格式化输出带宽度的字符串,%-10s 表示左对齐,宽度为 10
            ps.printf("|%-10s|%10s|\n", "姓名", "年龄");
            ps.printf("|%-10s|%10d|\n", name, age);

            // 格式化输出日期信息,使用 %tF 格式化日期为 yyyy-MM-dd 格式
            java.util.Date currentDate = new java.util.Date();
            ps.printf("当前日期: %tF\n", currentDate);

            // 格式化输出时间信息,使用 %tT 格式化时间为 HH:mm:ss 格式
            ps.printf("当前时间: %tT\n", currentDate);

            // 格式化输出带有前导零的整数,使用 %03d 表示宽度为 3,不足用 0 补齐
            int number = 7;
            ps.printf("带有前导零的数字: %03d\n", number);
        }
    }
}

运行输出:

姓名: Alice,年龄: 25 岁
姓名: Alice,身高: 1.65 米
姓名: Alice,是否为学生: true
|姓名      |      年龄|
|Alice     |        25|
当前日期: 2025-04-07
当前时间: 14:57:38
带有前导零的数字: 007

format()

PrintStream 类中的 format() 方法用于将格式化的字符串写入此输出流。它允许你使用格式化说明符来控制输出的格式,支持多种数据类型的格式化输出,例如整数、浮点数、字符串、日期等。

该方法有两个重载版本:

  • public PrintStream format(String format, Object... args):使用指定的格式字符串和参数生成格式化的输出。

  • public PrintStream format(Locale l, String format, Object... args):使用指定的语言环境、格式字符串和参数生成格式化的输出。

示例:

package com.hxstrive.java_io;

import java.io.PrintStream;
import java.util.Date;

public class PrintStreamFormatExample {
    public static void main(String[] args) {
        // 定义一些变量用于格式化输出
        String name = "John";
        int age = 30;
        double salary = 5000.50;
        Date currentDate = new Date();

        try(PrintStream ps = System.out) {
            // 示例 1:格式化输出字符串和整数
            // %s 用于格式化字符串,%d 用于格式化十进制整数
            ps.format("姓名: %s,年龄: %d\n", name, age);

            // 示例 2:格式化输出浮点数,保留两位小数
            // %.2f 表示格式化浮点数,保留两位小数
            ps.format("姓名: %s,薪水: %.2f\n", name, salary);

            // 示例 3:格式化输出日期
            // %tF 用于格式化日期为 yyyy-MM-dd 格式
            ps.format("当前日期: %tF\n", currentDate);

            // 示例 4:格式化输出带宽度和对齐的字符串
            // %-10s 表示左对齐,宽度为 10 的字符串格式化
            ps.format("|%-10s|%10d|\n", "姓名", age);
            ps.format("|%-10s|%10.2f|\n", name, salary);
        }
    }
}

运行结果:

姓名: John,年龄: 30
姓名: John,薪水: 5000.50
当前日期: 2025-04-07
|姓名      |        30|
|John      |   5000.50|

注意,format() 方法里,格式化字符串是由普通字符和格式说明符构成的。格式说明符以 % 开头,用于指定如何格式化相应的参数。以下是常见的格式说明符及其作用:

通用类型

格式说明符

说明

示例

%b、%B

用于格式化布尔类型的值。%b输出小写形式,%B输出大写形式。

System.out.format("%b", true);

输出 true

%s、%S

用于格式化字符串类型的值。%s输出小写形式(若适用),%S输出大写形式(若适用)。

System.out.format("%s", "hello");

输出 hello

%c、%C

用于格式化字符类型的值。%c输出小写形式,%C输出大写形式。

System.out.format("%c", 'A');

输出 A

数值类型

整数类型

格式说明符

说明

示例

%d

用于格式化十进制整数。

System.out.format("%d", 123);

输出 123

%o

用于格式化八进制整数。

System.out.format("%o", 123);

输出 173

%x、%X

用于格式化十六进制整数。%x输出小写字母,%X输出大写字母。

System.out.format("%x", 255);

输出 ff

浮点类型

格式说明符

说明

示例

%f

用于格式化十进制浮点数。默认保留 6 位小数。

System.out.format("%f", 3.14159);

输出 3.141590

%e、%E

用于格式化科学计数法表示的浮点数。%e输出小写 e,%E输出大写 E。

System.out.format("%e", 1234.56);

输出 1.234560e+03

%g、%G

根据数值大小自动选择 %f或 %e格式。%g输出小写形式,%G输出大写形式。

System.out.format("%g", 1234.56);

输出 1234.56

日期和时间类型

格式说明符

说明

示例

%t

这是日期和时间格式化的前缀,后面需要跟具体的日期时间转换字符。


%tY

输出年份,4 位数字。

System.out.format("%tY", new java.util.Date());

输出如 2024

%ty

输出年份的后两位数字。

System.out.format("%ty", new java.util.Date());

输出如 24

%tm

输出月份,两位数字(01 - 12)。

System.out.format("%tm", new java.util.Date());

输出如 04

%td

输出日期,两位数字(01 - 31)。

System.out.format("%td", new java.util.Date());

输出如 07

%tH

输出 24 小时制的小时数,两位数字(00 - 23)。

System.out.format("%tH", new java.util.Date());

输出如 14

%tM

输出分钟数,两位数字(00 - 59)。

System.out.format("%tM", new java.util.Date());

输出如 30

%tS

输出秒数,两位数字(00 - 60)。

System.out.format("%tS", new java.util.Date());

输出如 45

%tF

等价于 %tY-%tm-%td,输出 yyyy-MM-dd格式的日期。

System.out.format("%tF", new java.util.Date());

输出如 2024-04-07

%tT

等价于 %tH:%tM:%tS,输出 HH:mm:ss格式的时间。

System.out.format("%tT", new java.util.Date());

输出如 14:30:45

其他

格式说明符

说明

示例

%%

输出一个 %字符。

System.out.format("比例: 50%%");

输出 比例: 50%

%n

输出平台特定的换行符。

System.out.format("第一行%n第二行");

输出换行后的两行内容

格式说明符的修饰符

除了基本的格式说明符,还可以使用修饰符来进一步控制输出格式,常见修饰符如下:

  • 宽度:在 % 后指定一个正整数,表示输出的最小宽度。例如 %5d 表示输出的整数至少占 5 个字符宽度。

  • 精度:对于浮点数,在宽度后加 . 和数字表示保留的小数位数,如 %.2f 表示保留两位小数。

  • 对齐:- 表示左对齐,例如 %-10s 表示左对齐且宽度为 10 的字符串输出。

  • 正负号:+ 表示输出正负号,例如 %+d 会为正数也加上 + 号。

  • 前导零:0 表示用 0 填充宽度,例如 %05d 会在不足 5 位的整数前补 0。

关闭 PrintStream

当你完成向 PrintStream 写入数据的操作后,请务必记得将其关闭。需要注意的是,关闭 PrintStream 时,它所写入的 OutputStream 实例也会随之关闭。

若要关闭 PrintStream,只需调用其 close() 方法即可。例如:

printStream.close();

您还可以使用 Java 7 中引入的 try-with-resources 结构。例如

OutputStream output = new FileOutputStream("data.bin");
try(PrintStream printStream = new PrintStream(output)){
    printStream.writeInt(123);
    //...
}

需留意,此处不再有任何显式的 close() 方法调用,因为 try-with-resources 结构已自动处理了资源关闭问题。

另外,首个 FileOutputStream 实例并非在 try-with-resources 代码块中创建,这表明 try-with-resources 块不会自动关闭该 FileOutputStream 实例。不过,当 PrintStream 关闭时,它会同时关闭其写入数据的 OutputStream 实例,所以 FileOutputStream 实例会在 PrintStream 关闭时一并关闭。

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
其他应用
公众号