1. 标准输入输出流
System.in:标准的输入流,默认从键盘输入
System.out:标准的输出流,默认从控制台输出
System.err:标准的异常流,默认从控制台输出
2. jdk内源码
// FileDescriptor类 标准输出流的句柄。通常,此文件描述符不直接使用,而是通过称为 的 System.out输出流使用
public static final FileDescriptor out = standardStream(1);
// 标准输入流的句柄,不直接使用, 通常调用 System.in
public static final FileDescriptor in = standardStream(0);
// 标准异常输出流的句柄,不直接使用, 通常调用 System.err
public static final FileDescriptor err = standardStream(2);
// System 类
FileInputStream fdIn = new FileInputStream(FileDescriptor.in);
FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err);
setIn0(new BufferedInputStream(fdIn));
setOut0(newPrintStream(fdOut, props.getProperty("sun.stdout.encoding")));
setErr0(newPrintStream(fdErr, props.getProperty("sun.stderr.encoding")));
private static native void setIn0(InputStream in);
private static native void setOut0(PrintStream out);
private static native void setErr0(PrintStream err);
private static PrintStream newPrintStream(FileOutputStream fos, String enc) {
if (enc != null) {
try {
return new PrintStream(new BufferedOutputStream(fos, 128), true, enc);
} catch (UnsupportedEncodingException uee) {}
}
return new PrintStream(new BufferedOutputStream(fos, 128), true);
}
private static PrintStream newPrintStream(FileOutputStream fos, String enc) {
if (enc != null) {
try {
return new PrintStream(new BufferedOutputStream(fos, 128), true, enc);
} catch (UnsupportedEncodingException uee) {}
}
return new PrintStream(new BufferedOutputStream(fos, 128), true);
}
public static void setIn(InputStream in) {
checkIO();
setIn0(in);
}
//重新分配“标准”输出流,
public static void setOut(PrintStream out) {
checkIO();
setOut0(out);
}
public static void setErr(PrintStream err) {
checkIO();
setErr0(err);
}
3. 测试流输出 控制台–>文件–>控制台
这里的log和System.out 测试效果一样
package com.yl.test;
import lombok.extern.slf4j.Slf4j;
import java.io.*;
/**
* 测试重定向输出
*
* @author liuxubo
* @date 2023/3/19 22:21
*/
@Slf4j
public class TestPrint {
/**
* 创建控制台输出流,参考 {@link System newPrintStream(java.io.FileOutputStream, java.lang.String)}
*/
private static PrintStream printConsoleStream() {
FileOutputStream fos = new FileOutputStream(FileDescriptor.out);
String enc = System.getProperty("sun.stdout.encoding");
if (enc != null) {
try {
return new PrintStream(new BufferedOutputStream(fos, 128), true, enc);
} catch (UnsupportedEncodingException uee) {}
}
return new PrintStream(new BufferedOutputStream(fos, 128), true);
}
public static void main(String[] args) throws Exception {
//默认,控制台输出
log.info("锦瑟无端五十弦");
log.info("一弦一柱思华年");
// 改变输出语句的位置(重定向)
PrintStream ps = new PrintStream("D:/upload/test/aa.txt");
// 把系统打印流改成我们自己的打印流
System.setOut(ps);
log.info("庄生晓梦迷蝴蝶");
log.info("望帝春心托杜鹃");
//关闭输出到文件的流
ps.flush();
ps.close();
//恢复打印控制台的输出流
PrintStream out = printConsoleStream();
System.setOut(out);
log.info("-----------------");
log.info("庄生晓梦迷蝴蝶");
log.info("望帝春心托杜鹃");
log.info("-----------------");
}
}