JTextArea 內部統一使用 \n (LF, 0x0A) 作為換行符,但不同作業系統的文字檔慣例不同:
| 作業系統 | 換行符 | 十六進位 | 常見場景 |
|---|---|---|---|
| Windows | \r\n (CRLF) | 0x0D 0x0A | 記事本、大多數 Windows 編輯器 |
| Linux/Unix | \n (LF) | 0x0A | 原生文字檔、腳本、原始碼 |
| macOS (舊版) | \r (CR) | 0x0D | Classic Mac OS (OS 9 以前) |
| macOS (現代) | \n (LF) | 0x0A | Unix 相容 |
直接用 FileWriter 寫入 JTextArea.getText(),在 Windows 記事本開啟會顯示為單行(無法識別單獨 LF)。
try (PrintWriter pw = new PrintWriter(new FileWriter(file))) {
String text = textArea.getText();
for (String line : text.split("\n")) {
pw.println(line); // 自動使用系統行分隔符 (System.lineSeparator())
}
}
優點:自動適配平台、程式碼簡潔、緩衝寫入效能好。
缺點:split("\n") 會丟棄結尾空行,需額外處理。
byte[] content = textArea.getText().replace("\n", "\r\n").getBytes(StandardCharsets.UTF_8);
try (FileOutputStream fos = new FileOutputStream(file)) {
fos.write(content);
}
優點:一行搞定、保留所有換行結構。
缺點:大文本記憶體佔用雙倍、硬編碼 CRLF 不跨平台(僅適合 Windows 目標)。
try (FileWriter fw = new FileWriter(file)) {
String text = textArea.getText();
for (int i = 0; i < text.length(); i++) {
char c = text.charAt(i);
if (c == '\n') { // LF (10)
fw.write('\r'); // CR (13)
fw.write('\n');
} else {
fw.write(c);
}
}
}
優點:串流式處理、無額外記體、邏輯清晰。
缺點:逐字元寫入效能最差、硬編碼 CRLF。
public final class TextAreaUtils {
private TextAreaUtils() {}
/** 保存 JTextArea 內容,自動使用目標平台行分隔符 */
public static void saveTextArea(JTextArea textArea, File file, Charset charset) throws IOException {
String text = textArea.getText();
String targetEOL = System.lineSeparator(); // 當前 JVM 平台慣例
// 統一轉換:先正規化為 LF,再替換為目標 EOL
String normalized = text.replace("\r\n", "\n") // Windows -> LF
.replace("\r", "\n") // Old Mac -> LF
.replace("\n", targetEOL);
try (BufferedWriter writer = Files.newBufferedWriter(file.toPath(), charset)) {
writer.write(normalized);
}
}
/** 讀取檔案到 JTextArea,自動處理各種行分隔符 */
public static void loadTextArea(JTextArea textArea, File file, Charset charset) throws IOException {
String content = Files.readString(file.toPath(), charset);
// Swing 內部統一用 LF,讀取時正規化
String normalized = content.replace("\r\n", "\n").replace("\r", "\n");
textArea.setText(normalized);
}
}
// 使用範例
TextAreaUtils.saveTextArea(textArea, new File("note.txt"), StandardCharsets.UTF_8);
TextAreaUtils.loadTextArea(textArea, new File("note.txt"), StandardCharsets.UTF_8);
| 需求 | API | 說明 |
|---|---|---|
| 取得系統行分隔符 | System.lineSeparator() | JVM 運行平台慣例(Windows=\r\n, Linux/Mac=\n) |
| 取得系統屬性 | System.getProperty("line.separator") | 同 lineSeparator(),舊版寫法 |
| NIO 讀寫字串 | Files.readString/writeString | Java 11+,自動處理編碼、緩衝 |
| BufferedWriter 新行 | writer.newLine() | 等同 write(System.lineSeparator()) |
setText()StandardCharsets.UTF_8,避免平台預設編碼不一致BufferedWriter / NIO Files,避免全量載入記憶體JTextArea.getLineCount() / getLineStartOffset() 基於內部 LF 計算,不受檔案 EOL 影響DefaultEditorKit 處理剪貼簿時會自動轉換 EOL,通常無需干預