在Java程序中截获控制台输出
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
在程序中截获控制台输出
在开发中,控制台输出仍是一个重要的工具,但默认的控制台输出有着各种各样的局限。
本文介绍如何用管道流截取控制台输出,分析管道流应用中应该注意的问题,提供了截取程序和非程序控制台输出的实例。
即使在图形用户界面占统治地位的今天,控制台输出仍旧在程序中占有重要地位。
控制台不仅是程序默认的堆栈跟踪和错误信息输出窗口,而且还是一种实用的调试工具(特别是对习惯于使用()的人来说)。
然而,控制台窗口有着许多局限。
例如在平台上,控制台只能容纳行输出。
如果程序一次性向控制台输出大量内容,要查看这些内容就很困难了。
对于使用这个启动程序的开发者来说,控制台窗口尤其宝贵。
因为用启动程序时,根本不会有控制台窗口出现。
如果程序遇到了问题并抛出异常,根本无法查看运行时环境写入到或的调用堆栈跟踪信息。
为了捕获堆栈信息,一些人采取了用()块封装()的方式,但这种方式不一定总是有效,在运行时的某些时刻,一些描述性错误信息会在抛出异常之前被写入和;除非能够监测这两个控制台流,否则这些信息就无法看到。
因此,有些时候检查运行时环境(或第三方程序)写入到控制台流的数据并采取合适的操作是十分必要的。
本文讨论的主题之一就是创建这样一个输入流,从这个输入流中可以读入以前写入控制台流(或任何其他程序的输出流)的数据。
我们可以想象写入到输出流的数据立即以输入的形式“回流”到了程序。
本文的目标是设计一个基于的文本窗口显示控制台输出。
在此期间,我们还将讨论一些和管道流(和)有关的重要注意事项。
图一显示了用来截取和显示控制台文本输出的程序,用户界面的核心是一个。
最后,我们还要创建一个能够捕获和显示其他程序(可以是非的程序)控制台输出的简单程序。
一、管道流
要在文本框中显示控制台输出,我们必须用某种方法“截取”控制台流。
换句话说,我们要有一种高效地读取写入到和所有内容的方法。
如果你熟悉的管道流和,就会相信我们已经拥有最有效的工具。
写入到输出流的数据可以从对应的输入流读取。
的管道流极大地方便了我们截取控制台输出。
显示了一种非常简单的截取控制台输出方案。
【:用管道流截取控制台输出】
();
();
{
();
}
( ) {
("连接失败");
();
}
();
();
();
可以看到,这里的代码极其简单。
我们只是建立了一个,把它设置为所有写入控制台流的数据的最终目的地。
所有写入到控制台流的数据都被转到,这样,从相应的读取就可以迅速地截获所有写入控制台流的数据。
接下来的事情似乎只剩下在中显示从流读取的数据,得到一个能够在文本框中显示控制台输出的程序。
遗憾的是,在使用管道流时有一些重要的注意事项。
只有认真对待所有这些注意事项才能保证的代码稳定地运行。
下面我们来看第一个注意事项。
注意事项一
运用的是一个字节固定大小的循环缓冲区。
写入的数据实际上保存到对应的的内部缓冲区。
从执行读操作时,读取的数据实际上来自这个内部缓冲区。
如果对应的输入缓冲区已满,任何企图写入的线程都将被阻塞。
而且这个写操作线程将一直阻塞,直至出现读取的操作从缓冲区删除数据。
这意味着,向写数据的线程不应该是负责从对应读取数据的唯一线程。
假设线程是负责从读取数据的唯一线程;另外,假定企图在一次对的()方法的调用中向对应的写入字节的数据。
在线程阻塞之前,它最多能够写入字节的数据(内部缓冲区的大小)。
然而,一旦被阻塞,读取的操作就再也不会出现,因为是唯一读取的线程。
这样,线程已经完全被阻塞,同时,所有其他试图向写入数据的线程也将遇到同样的情形。
这并不意味着在一次()调用中不能写入多于字节的数据。
但应当保证,在写入数据的同时,有另一个线程从读取数据。
示范了这个问题。
这个程序用一个线程交替地读取和写入。
每次调用()向的缓冲区写入字节,每次调用()只从缓冲区读取并删除个字节。
内部缓冲区最终会被写满,导致写操作阻塞。
由于我们用同一个线程执行读、写操作,一旦写操作被阻塞,就不能再从读取数据。
【:用同一个线程执行读写操作导致线程阻塞】
.*;
{
();。