PrintWriter 字符打印流
如果你需要在 Java 中输出格式化的文本内容,PrintWriter 是比 PrintStream 更好的选择。
原因很简单:它支持字符编码。
基本用法
java
// 方式 1:包装 FileWriter(不能指定编码,不推荐)
try (PrintWriter pw = new PrintWriter("output.txt")) {
pw.println("第一行");
pw.printf("x = %d%n", 100);
}
// 方式 2:包装 OutputStreamWriter(推荐,可以指定编码)
try (PrintWriter pw = new PrintWriter(
new OutputStreamWriter(
new FileOutputStream("output.txt"), StandardCharsets.UTF_8))) {
pw.println("你好,PrintWriter!");
pw.printf("姓名: %s, 年龄: %d%n", "张三", 25);
}
// 方式 3:包装 BufferedWriter(更高效)
try (PrintWriter pw = new PrintWriter(
new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream("output.txt"), StandardCharsets.UTF_8)))) {
pw.println("第一行");
}和 PrintStream 的对比
| 对比 | PrintStream | PrintWriter |
|---|---|---|
| 底层类型 | 字节流 | 字符流 |
| 编码控制 | 不支持(需包装) | 支持(通过 OutputStreamWriter) |
| autoFlush 触发 | println / printf / write + autoFlush=true | 同左(仅对 OutputStream 包装时有效) |
| System.out | PrintStream | — |
| 推荐场景 | 二进制数据、调试输出 | 文本文件写入 |
printf 格式化
java
try (PrintWriter pw = new PrintWriter(
new OutputStreamWriter(
new FileOutputStream("output.txt"), StandardCharsets.UTF_8))) {
// 基本格式化
pw.printf("整数: %d%n", 42);
pw.printf("浮点: %.2f%n", 3.14159);
pw.printf("字符串: %s%n", "Hello");
// 宽度和对齐
pw.printf("右对齐: %10s%n", "Hi");
pw.printf("左对齐: %-10s%n", "Hi");
pw.printf("补零: %05d%n", 42);
// 多个参数
pw.printf("%s = %d, %s = %.2f%n", "age", 25, "height", 1.75);
}autoFlush
java
// autoFlush = true:对 OutputStream 包装时,println/printf/write 会自动 flush
try (PrintWriter pw = new PrintWriter(
new BufferedOutputStream(
new FileOutputStream("log.txt")), true)) {
pw.println("这条立即刷新");
pw.printf("格式化: %d%n", 42);
// 自动 flush,不需要手动调用
}
// autoFlush = false(默认):不自动 flush,需要手动 flush 或 close
try (PrintWriter pw = new PrintWriter(
new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream("log.txt"))))) {
pw.println("这条不立即刷新");
pw.flush(); // 手动刷新
// 或者 close 时自动 flush
}不抛异常
和 PrintStream 一样,PrintWriter 不抛 IOException:
java
PrintWriter pw = new PrintWriter("output.txt");
pw.println("数据");
if (pw.checkError()) {
// 检测到错误(磁盘满、IO异常等)
}写入 HTML 文件
java
try (PrintWriter pw = new PrintWriter(
new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream("page.html"), StandardCharsets.UTF_8)))) {
pw.println("<!DOCTYPE html>");
pw.println("<html>");
pw.println("<head><title>动态页面</title></head>");
pw.println("<body>");
pw.println("<h1>用户列表</h1>");
pw.println("<ul>");
for (User user : users) {
pw.printf("<li>%s (%d岁)</li>%n", user.getName(), user.getAge());
}
pw.println("</ul>");
pw.println("</body>");
pw.println("</html>");
}常见问题
自动刷新时机
java
// ❌ PrintWriter 包装 Writer 时,autoFlush 不起作用
try (PrintWriter pw = new PrintWriter(
new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream("out.txt"))))) {
pw.println("不会自动 flush");
// autoFlush 只对 OutputStream 包装有效,对 Writer 包装无效
}
// ✅ 正确做法:手动 flush
try (PrintWriter pw = new PrintWriter(
new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream("out.txt"))))) {
pw.println("手动刷新");
pw.flush();
}Writer 和 OutputStream 的选择
java
// 如果你需要 autoFlush,包装 OutputStream
try (PrintWriter pw = new PrintWriter(
new BufferedOutputStream(
new FileOutputStream("log.txt")), true)) { // true = autoFlush
pw.println("立即刷新");
}
// 如果你需要指定编码,包装 OutputStreamWriter
try (PrintWriter pw = new PrintWriter(
new OutputStreamWriter(
new FileOutputStream("data.txt"), StandardCharsets.UTF_8))) {
pw.println("UTF-8 编码");
pw.flush(); // 手动刷新
}记住这个原则:
写文本文件,用
PrintWriter。 永远用OutputStreamWriter包装并指定编码。
