PrintWriter 是字元導向的列印輸出流,繼承自 Writer。它專為格式化文字輸出設計,提供豐富的 print()、println()、printf()、format() 方法,能將各種基本型別與物件自動轉換為字串輸出。與 PrintStream(位元組導向)不同,PrintWriter 直接處理字元,支援指定字元集,適合文字檔案輸出與國際化場景。
| 建構子 | 輸出目標 | 自動刷新 | 字元集 |
|---|---|---|---|
| PrintWriter(Writer out) | 字元流 | false | 預設 |
| PrintWriter(Writer out, boolean autoFlush) | 字元流 | 可指定 | 預設 |
| PrintWriter(OutputStream out) | 位元組流 | false | 預設 |
| PrintWriter(OutputStream out, boolean autoFlush) | 位元組流 | 可指定 | 預設 |
| PrintWriter(String fileName) | 檔案路徑 | false | 預設 |
| PrintWriter(String fileName, String csn) | 檔案路徑 | false | 指定 |
| PrintWriter(File file) | File 物件 | false | 預設 |
| PrintWriter(File file, String csn) | File 物件 | false | 指定 |
當 autoFlush=true 時,呼叫 println()、printf()、format() 或寫入換行符會自動觸發 flush()。注意:print() 不會觸發自動刷新,僅 println() 等換行操作會。
// 格式化輸出
PrintWriter printf(String format, Object... args)
PrintWriter printf(Locale l, String format, Object... args)
PrintWriter format(String format, Object... args)
PrintWriter format(Locale l, String format, Object... args)
// 列印方法(自動轉字串)
void print(boolean b) / print(char c) / print(int i) / print(long l)
void print(float f) / print(double d) / print(char[] s) / print(String s) / print(Object obj)
void println() / println(boolean x) / println(char x) / println(int x) / println(long x)
void println(float x) / println(double x) / println(char[] x) / println(String x) / println(Object x)
// 字元寫入(Writer 基礎方法)
void write(int c) / write(char[] cbuf) / write(char[] cbuf, int off, int len)
void write(String str) / write(String str, int off, int len)
// 追加與檢查
PrintWriter append(char c) / append(CharSequence csq) / append(CharSequence csq, int start, int end)
boolean checkError() // 檢查是否發生錯誤,不拋出異常
void flush() / void close()
public class PrintWriter extends Writer {
protected Writer out; // 底層字元輸出流
private final boolean autoFlush; // 自動刷新旗標
private boolean trouble = false; // 錯誤旗標
private Formatter formatter; // 格式化器
private PrintStream psOut = null; // 若包裝 PrintStream,用於錯誤傳播
private final String lineSeparator; // 系統行分隔符
// ...
}
所有寫入方法捕獲 IOException 並設置 trouble = true,不向外拋出。呼叫端需主動呼叫 checkError() 檢查狀態。這設計簡化了列印邏輯,但需開發者養成檢查習慣。
建構子接受 OutputStream 時,內部會建立 OutputStreamWriter(指定或預設編碼)再包裝 BufferedWriter,實現位元組到字元的編碼轉換與緩衝。
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
public class PrintWriterDemo {
public static void main(String[] args) {
demoConstructors();
demoFormatting();
}
// 三種常見建構方式寫入相同內容
private static void demoConstructors() {
char[] data = {'a', 'b', 'c', 'd', 'e'};
// 方式 1:包裝 FileOutputStream
try (PrintWriter pw = new PrintWriter(new FileOutputStream("file1.txt"))) {
pw.write(data);
} catch (IOException e) { e.printStackTrace(); }
// 方式 2:直接指定 File
try (PrintWriter pw = new PrintWriter(new File("file2.txt"))) {
pw.write(data);
} catch (IOException e) { e.printStackTrace(); }
// 方式 3:指定檔名與 UTF-8 編碼
try (PrintWriter pw = new PrintWriter("file3.txt", StandardCharsets.UTF_8.name())) {
pw.write(data);
} catch (IOException e) { e.printStackTrace(); }
}
// 格式化、列印、追加綜合示範
private static void demoFormatting() {
try (PrintWriter pw = new PrintWriter("formatted.txt", StandardCharsets.UTF_8.name())) {
pw.println("=== 格式化輸出示範 ===");
pw.printf("整數: %d, 十六進位: 0x%X%n", 255, 255);
pw.printf("浮點: %.2f, 科學記號: %e%n", Math.PI, Math.PI);
pw.format(Locale.TAIWAN, "本地化數字: %,d%n", 1234567);
pw.print("直接列印: ");
pw.print(true).print(' ').print(3.14).println(" 結束");
pw.append('[').append("APPEND").append(']').println();
// 錯誤檢查
if (pw.checkError()) {
System.err.println("PrintWriter 發生錯誤!");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
| 特性 | PrintWriter | PrintStream |
|---|---|---|
| 資料單位 | 字元 | 位元組 |
| 編碼支援 | 建構子可指定字元集 | 建構子可指定字元集(JDK 1.4+) |
| 自動刷新觸發 | println/printf/format/換行符 | println/printf/format/換行符 |
| 異常處理 | 吞噬,checkError() 檢查 | 吞噬,checkError() 檢查 |
| 適用場景 | 文字檔、報表、日誌、國際化 | 控制台、位元組導向輸出、System.out |
PrintWriter(file, StandardCharsets.UTF_8.name()) 避免平台預設編碼差異。printf/format 比字串串接效能更好、可讀性更高,支援區域化數字格式。checkError() 並記錄日誌。Writer,建議先包裝 BufferedWriter 再傳給 PrintWriter。PrintWriter 是 Java 文字格式化輸出的利器,掌握其建構選項、自動刷新行為與錯誤處理模式,能讓檔案寫入、報表產生、日誌記錄等工作更加優雅可靠。