本文提供一個互動式命令列程式範例,示範如何從標準輸入(鍵盤)讀取資料,同時寫入檔案與標準輸出(螢幕),以 # 開頭的行作為結束信號。涵蓋 FileOutputStream 位元組流寫入、緩衝處理、例外處理與資源管理完整流程。
import java.io.*;
public class WriteFile {
public static void main(String[] args) {
// 1. 參數檢查
if (args.length == 0) {
System.err.println("用法: java WriteFile <輸出檔案路徑>");
System.exit(1);
}
byte[] buffer = new byte[1024];
FileOutputStream fos = null;
try {
// 2. 開啟檔案輸出流(覆寫模式)
fos = new FileOutputStream(args[0]);
System.out.println("開始輸入(以 # 開頭的行結束):");
// 3. 迴圈讀取標準輸入
int bytesRead;
while ((bytesRead = System.in.read(buffer)) != -1) {
// 同步輸出到螢幕
System.out.write(buffer, 0, bytesRead);
// 檢查結束條件:第一個位元組為 '#'
if (buffer[0] == '#') {
break;
}
// 寫入檔案
fos.write(buffer, 0, bytesRead);
}
} catch (FileNotFoundException e) {
System.err.println("無法建立檔案: " + args[0]);
System.exit(1);
} catch (IOException e) {
System.err.println("讀寫錯誤: " + e.getMessage());
System.exit(1);
} finally {
// 4. 確保關閉資源
if (fos != null) {
try { fos.close(); }
catch (IOException e) { System.err.println("關閉檔案失敗"); }
}
}
}
}
javac WriteFile.java
java WriteFile output.txt
# 輸入任意文字,按 Enter 送出
# 結束輸入
# 程式結束,output.txt 將包含除結束行外的所有內容
| 步驟 | 說明 |
|---|---|
| 開啟 FileOutputStream | 預設覆寫模式;若需附加模式用 new FileOutputStream(file, true) |
| System.in.read(buffer) | 阻塞讀取鍵盤輸入,回傳實際位元組數(含換行符) |
| System.out.write(...) | 將原始位元組直接輸出到螢幕(不經編碼轉換) |
| buffer[0] == '#' | 簡易結束判斷:行首字元為 # 即跳出迴圈,不寫入檔案 |
| fos.write(...) | 將同樣位元組寫入檔案 |
read() 會分多次回傳,邏輯仍正確;但結束判斷 buffer[0] == '#' 僅檢查每次讀取的第一個位元組,若 # 不在緩衝區起始位置將無法偵測(極少見)。finally 區塊確保 fos.close() 執行,Java 7+ 建議改用 try-with-resources。import java.io.*;
import java.nio.charset.StandardCharsets;
public class WriteFileModern {
public static void main(String[] args) throws IOException {
if (args.length == 0) {
System.err.println("用法: java WriteFileModern <輸出檔案路徑>");
return;
}
try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8));
BufferedWriter bw = new BufferedWriter(
new OutputStreamWriter(new FileOutputStream(args[0]), StandardCharsets.UTF_8))) {
System.out.println("開始輸入(以 # 開頭的行結束):");
String line;
while ((line = br.readLine()) != null) {
System.out.println(line); // 螢幕輸出
if (line.startsWith("#")) break;
bw.write(line);
bw.newLine(); // 跨平台換行
}
} // 自動關閉所有資源
}
}
new FileOutputStream(file, true) 或 Files.newBufferedWriter(path, StandardOpenOption.APPEND)BufferedOutputStream 包裝 FileOutputStream,或直接用 BufferedWriterAsynchronousFileChannel 適用高併發場景FileChannel.lock() 防止多進程同時寫入檔案寫入核心在於:正確開啟流、緩衝讀寫、精確控制結束條件、確保資源釋放。現代開發強烈建議使用 字元流 + try-with-resources + 明確編碼(UTF-8),避免編碼亂碼與資源洩漏,並獲得更好的可讀性與維護性。