打印流(PrintWriter)
如果你觉得 BufferedWriter 写文本还不够方便,试试 PrintWriter。
它的核心特点:不抛异常,而且 printf() 格式化输出是内置的。
PrintWriter 的特点
- 不抛异常:写入失败不会抛
IOException,内部维护一个Writer - 自动 flush:当写入换行符或调用
println()时自动 flush(如果启用了 autoFlush) - 格式化输出:支持
printf()风格的格式化字符串 - 字符流本质:操作
char而非byte,天然适合文本输出
基本用法
java
// 构造方式一:直接指定文件路径
try (PrintWriter pw = new PrintWriter("output.txt")) {
pw.println("第一行");
pw.println("第二行");
}
// 构造方式二:指定编码
try (PrintWriter pw = new PrintWriter(
new OutputStreamWriter(
new FileOutputStream("output.txt"), StandardCharsets.UTF_8))) {
pw.println("UTF-8 编码的内容");
}
// 构造方式三:autoFlush 模式(println 时自动 flush)
try (PrintWriter pw = new PrintWriter(
new FileWriter("output.txt"), true)) { // true = autoFlush
pw.println("自动 flush"); // 写完立即刷新到磁盘
}printf 格式化输出
PrintWriter 继承自 Writer,但通过 printf() / format() 支持格式化:
java
try (PrintWriter pw = new PrintWriter(System.out, true)) {
// %d = 整数, %s = 字符串, %.2f = 两位小数浮点
pw.printf("用户名: %s, 年龄: %d, 积分: %.2f%n", "张三", 25, 1234.567);
// 输出:用户名: 张三, 年龄: 25, 积分: 1234.57
}常用格式化符号
| 符号 | 说明 | 示例 |
|---|---|---|
%d | 十进制整数 | %d → 42 |
%s | 字符串 | %s → hello |
%.2f | 浮点数,保留 2 位 | %.2f → 3.14 |
%n | 平台换行符 | 等价于 System.lineSeparator() |
%t | 日期/时间 | %tF → 2024-01-15 |
与 PrintStream 的区别
| 特性 | PrintStream | PrintWriter |
|---|---|---|
| 底层 | 字节流(OutputStream) | 字符流(Writer) |
| 目标 | 文件、控制台、网络 | 文件、Writer |
| 编码支持 | 字节为单位,无编码 | 可指定字符编码 |
| 推荐场景 | 字节数据、日志(System.out) | 文本文件写入(推荐) |
java
// ❌ 写文本文件不推荐用 PrintStream
try (PrintStream ps = new PrintStream("output.txt")) {
ps.println("这是字节流写入");
}
// ✅ 推荐用 PrintWriter 写文本
try (PrintWriter pw = new PrintWriter("output.txt", StandardCharsets.UTF_8)) {
pw.println("这是字符流写入");
}自动 flush 的时机
java
// autoFlush = false(默认)
PrintWriter pw = new PrintWriter(new FileWriter("output.txt"));
pw.print("不会自动 flush"); // 可能在缓冲区
pw.close(); // close 时才真正写入
// autoFlush = true
PrintWriter pw = new PrintWriter(new FileWriter("output.txt"), true);
pw.println("写完一行立即 flush"); // println 自动 flush常见用法:写日志
java
public class Logger {
private final PrintWriter writer;
public Logger(String path) throws IOException {
this.writer = new PrintWriter(
new BufferedWriter(
new FileWriter(path, true)), // 追加模式
true); // autoFlush
}
public void info(String msg) {
writer.printf("%tF %tT [INFO] %s%n",
new Date(), new Date(), msg);
}
public void error(String msg, Throwable t) {
writer.printf("%tF %tT [ERROR] %s: %s%n",
new Date(), new Date(), msg, t.getMessage());
}
public void close() {
writer.close();
}
}记住这个选择:
写文本文件,用
PrintWriter。 写字节数据或调试输出,用PrintStream。
