基于本文回答

播面 播面

文图音视,全方位拆解八股文
0
评论

讲讲 Java中PrintStream 和 PrintWriter的区别

在Java中,PrintStreamPrintWriter 都是用于格式化输出的包装流(Wrapper Stream),它们提供了极其相似的 API(如 print()println()printf())。

但是,它们在底层实现、处理的数据类型以及适用场景上有本质的区别。以下是它们的核心区别和详细对比:


1. 核心区别:字节流 vs 字符流

这是两者最根本的区别:

  • PrintStream 是字节流(Byte Stream)
    • 它继承自 FilterOutputStream(间接继承自 OutputStream)。
    • 它主要用于处理字节数据(如图片、视频、二进制文件,或者默认编码的文本)。
    • 我们最常用的 System.outSystem.err 就是 PrintStream 的实例。
  • PrintWriter 是字符流(Character Stream)
    • 它继承自 Writer
    • 它专门用于处理字符数据(文本)。
    • 由于它是字符流,它能更好地支持国际化(I18N),能够自动且正确地处理各种字符编码(如 UTF-8、GBK 等)。

2. 详细对比

特性 PrintStream PrintWriter
继承关系 OutputStream -> FilterOutputStream -> PrintStream Writer -> PrintWriter
处理单位 字节(Byte) 字符(Char,2字节)
国际化/编码 较弱。虽然可以指定编码,但其本质是字节流,转换过程中可能出错。 极佳。原生支持字符编码,能自动处理 Unicode 字符。
自动刷新 (Auto-flush) 当写入字节数组、调用 println() 或写入换行符 '\n' 时触发。 仅在调用 println()printf()format() 方法时触发(写入 '\n' 不会触发)。
常见应用 控制台输出(System.out)、向套接字(Socket)写入原始字节。 文本文件写入、Web 开发中向浏览器返回 HTML/JSON(如 Servlet 的 response.getWriter())。
异常处理 都不抛出 IOException。它们内部捕获了异常,需要通过 checkError() 方法手动检查。

3. 自动刷新(Auto-flush)的细微区别

两者都可以通过构造函数启用“自动刷新”功能(autoFlush = true),但触发条件略有不同:

  • PrintStream 的触发条件
    1. 调用了 println() 方法。
    2. 写入了换行符 '\n'
    3. 写入了字节数组(write(byte[]))。
  • PrintWriter 的触发条件
    1. 调用了 println()printf()format() 方法。
    2. 注意:仅仅写入 '\n' 字符不会触发 PrintWriter 的自动刷新。

4. 代码示例对比

示例 1:使用 PrintStream 写入文件(字节操作)

java
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;

public class PrintStreamExample {
    public static void main(String[] args) {
        try (PrintStream ps = new PrintStream(new FileOutputStream("log.txt"))) {
            ps.println("Hello World");
            ps.printf("Format number: %.2f\n", 3.14159);
            // 内部捕获了异常,不需要显式 try-catch 每一个 write
            if (ps.checkError()) {
                System.out.println("写入过程中发生错误");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

示例 2:使用 PrintWriter 写入文件(字符/文本操作,推荐)

java
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

public class PrintWriterExample {
    public static void main(String[] args) {
        // PrintWriter 允许指定编码,对中文等支持更好
        try (PrintWriter pw = new PrintWriter(new FileWriter("info.txt"))) {
            pw.println("你好,世界!"); // 完美支持中文
            pw.printf("商品价格: %.2f 元\n", 99.9);
            
            if (pw.checkError()) {
                System.out.println("写入过程中发生错误");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

5. 总结与选型建议

  1. 优先选择 PrintWriter
    当你在写纯文本文件网页内容或任何涉及字符/文字的输出时,应该优先使用 PrintWriter。它对字符编码的支持更安全、更健壮。
  2. 选择 PrintStream 的场景
    • 当你需要向控制台输出调试信息时(通常直接用 System.out)。
    • 当你需要处理原始字节,或者目标输出流是 OutputStream 且你不想将其包装成 Writer 时。
00:00
00:00