System.out与System.err的区别
关键的几点:
System.out输出也许会重定向,而使用System.err会将错误发送给标准错误流,不会被重定向,这样更容易被用户注意。
标准输出往往是带缓存的,而标准出错没有缓存(默认设置,可以改)。所以如果你用标准出错打印出来的东西可以马上显示在屏幕,而标准输出打印出来的东西可能要再积累几个字符才能一起打印出来。
TestMyException.java
package com.jacky.study.exception;
import org.apache.log4j.Logger;
/**
* System.out输出也许会重定向,而使用System.err会将错误发送给标准错误流,不会被重定向,这样更容易被用户注意.
*
* @author chenjie
* @times 2014-2-18 上午9:52:50
*
*/
public class TestMyException {
private static Logger logger = Logger.getLogger(TestMyException.class);
public static void f() throws MyException {
System.out.println("in f method");
throw new MyException();
}
public static void testPrint() {
try {
f();
} catch (MyException e) {
// e.printStackTrace();
/*
* 标准输出往往是带缓存的,而标准出错没有缓存(默认设置,可以改)。所以如果你用标准出错打印出来的东西可以马上显示在屏幕,
* 而标准输出打印出来的东西可能要再积累几个字符才能一起打印出来。
*/
System.out.println("out:我可以catch it!");
System.err.println("err:catch it!");
logger.error("log4j:catch it!");
}
logger.info("log4j:done!");
}
public static void main(String[] args) {
testPrint();
}
}
MyException.java
package com.jacky.study.exception;
import java.util.Date;
public class MyException extends Exception {
private static final long serialVersionUID = 1L;
private String errorMsg;
public MyException() {
super((new Date()) + "");
}
public MyException(String msg) {
super((new Date()) + " " + msg);
}
@Override
public String getMessage() {
// TODO Auto-generated method stub
return super.getMessage();
}
public String getErrorMsg() {
return errorMsg;
}
public void setErrorMsg(String errorMsg) {
this.errorMsg = errorMsg;
}
}
将System.out重定向到log4j的例子一:
RecursiveLogging.java
package com.jacky.study.exception;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import org.apache.log4j.Logger;
/**
* 将System.out重定向到log4j.
*
* @author chenjie
* @times 2014-2-18 上午11:10:36
*
*/
public class RecursiveLogging {
public static void main(String[] args) {
System.setOut(new PrintStream(new CustomOutputStream()));
TestMyException.testPrint();
}
}
class CustomOutputStream extends OutputStream {
private Logger logger = Logger.getLogger(this.getClass());
@Override
public final void write(int b) throws IOException {
// the correct way of doing this would be using a buffer
// to store characters until a newline is encountered,
// this implementation is for illustration only
logger.info((char) b);
}
@Override
public void write(byte[] b, int off, int len) throws IOException {
if (b == null) {
throw new NullPointerException();
} else if ((off < 0) || (off > b.length) || (len < 0) ||
((off + len) > b.length) || ((off + len) < 0)) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return;
}
byte[] pb = new byte[len];
for (int i = 0 ; i < len ; i++) {
pb[i] = (b[off + i]);
}
String str = new String(pb);
logger.info(str);
}
}
将System.out重定向到log4j的例子二:
RecursiveLogging2.java
package com.jacky.study.exception;
import java.io.OutputStream;
import java.io.PrintStream;
import org.apache.log4j.Logger;
public class RecursiveLogging2 {
static {
Log4jPrintStream.redirectSystemOut();
}
public static void main(String[] args) {
TestMyException.testPrint();
}
}
class Log4jPrintStream extends PrintStream {
private Logger logger = Logger.getLogger("SystemOut");
private static PrintStream instance = new Log4jPrintStream(System.out);
private Log4jPrintStream(OutputStream out) {
super(out);
}
public static void redirectSystemOut() {
System.setOut(instance);
}
public void print(boolean b) {
println(b);
}
public void print(char c) {
println(c);
}
public void print(char[] s) {
println(s);
}
public void print(double d) {
println(d);
}
public void print(float f) {
println(f);
}
public void print(int i) {
println(i);
}
public void print(long l) {
println(l);
}
public void print(Object obj) {
println(obj);
}
public void print(String s) {
println(s);
}
public void println(boolean x) {
logger.debug(Boolean.valueOf(x));
}
public void println(char x) {
logger.debug(Character.valueOf(x));
}
public void println(char[] x) {
logger.debug(x == null ? null : new String(x));
}
public void println(double x) {
logger.debug(Double.valueOf(x));
}
public void println(float x) {
logger.debug(Float.valueOf(x));
}
public void println(int x) {
logger.debug(Integer.valueOf(x));
}
public void println(long x) {
logger.debug(x);
}
public void println(Object x) {
logger.debug(x);
}
public void println(String x) {
logger.debug(x);
}
}