文档章节

拦截System.out和System.err

markdrord
 markdrord
发布于 2015/03/02 18:16
字数 414
阅读 26
收藏 0

System.out和System.err是Java的默认输出,大家对此都是非常熟悉的,但是你想过如何对他们进行拦截,而将输入转移到其他位置吗?

你可能想只需要对System.out和System.err做一个代理就好了,ok,就是这么回事,然后通过System.setOut和System.setErr方法将代理传给JVM,但是到底怎么做呢?因为他们的类型是java.io.PrintStream,是不是写一个类PrintStreamProxy代理所有的public方法就行了呢,如果你阅读了源代码的话会发现这样做会遇到很多问题,具体什么问题大家试一试就知道了,本文说的是另外一种代理。

因为java.io.PrintStream有一个是用java.OutputStream的构造方法,所有的输出最终都是通过OutputStream完成的,所有拦截它可以达到同样的效果。

下面就是代码了:

abstract class Monitor extends OutputStream {

		private PrintStream real;
		private List<Byte> buffer;

		private char lineChar;

		public Monitor(PrintStream printStream) {
			this.real = printStream;
			this.buffer = this.createByteBuffer ();
			String s = System.getProperty("line.separator");
			lineChar = s.charAt(s.length() -1);
		}

		PrintStream getReal() {
			return real;
		}

		@Override
		synchronized
		public void write(int b) throws IOException {
			buffer.add(Integer.valueOf(b).byteValue());

			if (b == lineChar) {
				String line = makeString();
				LogLine obj = createObject(line);
				Event event = new Event(Monitor.this, obj);
				try {
					publisher.publish(event);
				} catch (Throwable t) {
					onError(t, line);
				} finally {
					real.print(line);
				}
			}
		}

		protected String makeString() {
			byte[] bs = new byte[buffer.size()];
			for (int i=0; i<buffer.size(); i++) {
				bs[i] = buffer.get(i);
			}
			String str = new String(bs);
			buffer = this.createByteBuffer ();
			return str;
		}

		protected List<Byte> createByteBuffer () {
			return new ArrayList<Byte>(200);
		}

		protected abstract LogLine createObject(String str);

		protected void onError(Throwable t, String str) {

		}

	}

通过代码可以知道只需要代理java.io.OutputStream的write方法就可以了,并且可以将每次输出的一行字符串发送给外界。

如果要代理System.out可以这样写

System.setOut(new PrintStream(new Monitor(){
	...
}));


© 著作权归作者所有

共有 人打赏支持
markdrord
粉丝 1
博文 7
码字总数 2329
作品 0
浦东
技术主管
私信 提问
hadoop 2.6 mapreduce 自定义log 的查看方法

作者 用的 hadoop 2.6.0 其它版本的忘记了 看不到的log 在我们平时的hadoop mapreduce 运行中 大家都会发现 不管在mapreduce 中用 System.out 还是System.err,还是log4j 等等 在yarn 下图中...

疯code
2016/08/18
11
0
System.out.println与System.err.println的区别

1、System.out.println 能重定向到别的输出流,这样的话你在屏幕上将看不到打印的东西了, 而System.err.println只能在屏幕上实现打印,即使你重定向了也一样。 System.setOut(new PrintStr...

Sandy_wu
2013/03/22
0
0
android.os.NetworkOnMainThreadException 如何解决

06-15 12:39:52.554 22666-22666/com.qrbike.app W/System.err﹕ android.os.NetworkOnMainThreadException 06-15 12:39:52.556 22666-22666/com.qrbike.app W/System.err﹕ at android.os.......

wffger
2014/06/15
1K
3
安卓学习之三种输出日志信息方法

①日志优先级:ERROR>WARN>INFO>DEBUG>UERBOSE ②private static final String TAG="LogTest"; String msg="liang"; 第一种:Log.i(TAG,msg); tag为TAG,级别是Info 第二种:System.out.print......

湖心亭看雪
2014/06/13
0
0
Android查看stdout 和stderr

在默认状态下,Android系统有stdout和stderr(System.out和System.err)输出到/dev/null,在运行Dalvik VM的进程中,有一个系统可以备份日志文件。在这种情况下,系统会用stdout和stderr和优先...

shouyong
2013/01/17
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Navicat怎样导入Excel表格和txt文本的数据

Navicat怎样导入Excel表格和txt文本的数据 2018年07月02日 11:29:11 零碎de記憶 阅读数:2433 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_39135287/ar...

linjin200
16分钟前
0
0
使用MaxCompute Java SDK运行安全相关命令

使用MaxCompute Console的同学,可能都使用过MaxCompute安全相关的命令。官方文档上有详细的MaxCompute 安全指南 ,并给出了安全相关语句汇总 。 简而言之, 权限管理 、 列级别访问控制 、 ...

阿里云云栖社区
20分钟前
0
0
中小公司的Java工程师应该如何逆袭冲进BAT?

(1)80% Java工程师都有的迷茫 这篇文章,跟大家聊一聊很多很多很多人问我的一个问题:中小公司的Java工程师应该如何规划准备,才能跳槽进入BAT这类一线互联网公司? 之所以我用了三个 “很...

Java填坑路
21分钟前
2
0
你的应用够安全吗?绿标2.0隐私权限详解

近日,最新一期的《绿色应用达标率调查报告》结果显示,应用在安全方面的通过率仅为57%,相较于其他四项标准通过率最低。其中隐私权限的过度获取是主要原因之一,需要开发者尽快完成整改。 ...

安卓绿色联盟
31分钟前
0
0
使用MaxCompute Java SDK运行安全相关命令

使用MaxCompute Console的同学,可能都使用过MaxCompute安全相关的命令。官方文档上有详细的MaxCompute安全指南,并给出了安全相关语句汇总。 简而言之,权限管理、列级别访问控制、项目空间...

阿里云官方博客
36分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部