System.out là PrintStream mặc định trỏ tới console. Dùng System.setOut() để đổi đích ra file.
Cách làm
- Tạo
Fileobject - Tạo
PrintStreamwrapping file đó - Gọi
System.setOut(printStream) - Tất cả
System.out.println()sau đó sẽ ghi vào file
Ví dụ
import java.io.*;
public class RedirectSystemOut {
public static void main(String[] args) throws IOException {
File logFile = new File("D:/app.log");
// Tự động tạo file, ghi đè (append = false mặc định)
// Dùng new PrintStream(file, true) để append
try (PrintStream ps = new PrintStream(logFile, "UTF-8")) {
System.out.println("Đang ghi ra console (trước setOut)");
System.setOut(ps);
System.out.println("Dòng 1: Ghi vào file");
System.out.println("Dòng 2: Cũng ghi vào file");
System.out.printf("Format: %s = %d%n", "Pi", 3.14);
}
// Sau try-with-resources, stream đã close, System.out vẫn trỏ tới file đã đóng!
// Cần restore nếu muốn tiếp tục dùng console
System.out.println("Dòng này sẽ lỗi (stream closed) hoặc không hiển thị!");
}
}
⚠️ Vấn đề quan trọng: Restore System.out
Sau khi đóng PrintStream, System.out trỏ tới stream đã đóng. Cần lưu reference gốc:
PrintStream originalOut = System.out;
try (PrintStream ps = new PrintStream("log.txt")) {
System.setOut(ps);
System.out.println("Vào file");
}
System.setOut(originalOut); // QUAN TRỌNG: Khôi phục
System.out.println("Quay lại console");
Ghi append (không ghi đè)
// PrintStream(File, boolean append) – Java 10+
// Hoặc dùng FileOutputStream với append=true
PrintStream ps = new PrintStream(new FileOutputStream("log.txt", true));
Ứng dụng thực tế: Logging đơn giản
public class SimpleLogger {
private static final PrintStream LOG;
static {
try {
LOG = new PrintStream(new FileOutputStream("app.log", true), true, "UTF-8");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static void log(String msg) {
LOG.printf("[%tF %tT] %s%n", System.currentTimeMillis(), System.currentTimeMillis(), msg);
}
}