1回顶部 由于前段时间一个网友写信询问如何在运行其他可执行程序时将控制台的输入提交到它想运行的程序,由于考虑到他的特殊情况就帮他弄了一下,刚开始想着这个问题应该比较简单,但是在实际做的过程中才发现有很多陷阱,而且好像不能弄一个非常通用的东西出来。下面的代码是我想做出的一个通用封装器的尝试:import java.io.*; 我以native2ascii为范例程序和网友给我的那个程序做了对比,发现如下几个在处理这个问题时需要注意的地方: 2回顶部 1、由于不知道目标程序的输入输出顺序,因此只能建立两个单独的线程分别处理输入和输出,这样输入和输出就不会阻塞了。但是有些目标程序要求有特定的输入输出顺序,而经过这个类封装的结果是在任何状态下都可以输入,程序的任何输出也会被马上反映出来,构造通用类的第一个问题。 2、不能直接使用I/O重定向,在最开始的时候我是考虑直接使用I/O重定向的,但是实际的情况是Process的I/O的定义刚好和我的预想相反,我们从Process取得的InputStream实际上是它的输出,而取得的OutputStream是它的输入,这样就无法进行I/O重定向了,必须我们进行编码来读取程序的输出和写入控制台的输入。(这里的I/O重定向是指想将它的I/O直接重定向到系统的I/O) 3、写入控制台的输入: outputStream.write 这里有两个问题值得注意:第一个是我们在控制台输入一行数据以后按下回车,那么语句reader.readLine()可以正确的得到你的输入,为什么要加那个换行符呢? 这是在测试的时候发现的问题,在以native2ascii作为例子的时候发现不加这个的话它不能得到控制台的输入,但是我在替那位网友解决的问题的时候他的程序则没有这个问题,因此猜想可能是因为有的程序要求读取的一整行的数据(例如native2ascii),而大部分的命令行程序在编码的时候读取的是整数这样的值或者其他类型的值,他们是以空格或者其他的字符分隔的,因此就不需要那个额外的换行符(例如那位网友的程序读取的是一元二次方程的三个系数)。 另外一个问题就是flush方法的使用,在最开始的时候没有想到要这样刷新进去,无论是否加换行符外部程序都无法读取写入的输入,后来才想到要调用一下这个方法。这个也是在我们输出的时候应该注意的一个问题,有些需要马上反应出来的输出一般都在写入以后要调用它,否则输出/输入不能马上反应出来。 3回顶部 4、对于程序的输出,最开始我是构造的一个BufferedReader想以行为单位输出,对于那位网友的程序,结果证明不是很好用,但是以native2ascii作为例子运行又没有问题。这个估计和外部程序的代码也有关系,如果外部程序没有输出换行符可能使用BufferedReader就会有问题。但是通过直接读取输出就没有问题了。另外需要注意的就是: System.out.println(lineNumber+":"+new 中严格来说应该是: System.out.println(lineNumber+":"+ 之所以减一是因为读取输入的时候人为的多加了一个换行符,如果这个地方不减一就会多输出一个空行。 基于以上的种种原因,要构造一个执行外部程序的包装器类不太好办,特别是文章中提到的几个问题。有时间和兴趣的朋友可以做一下测试,看看以上的问题和猜测是否正确。另外附上网友的源代码,是一个fortran的程序: implicit none 在最开始给出的那个类虽然在某些应用中可能存在问题,但是对于一般的程序可能问题不是很大,当然大家可以根据上面的说明、猜测在应用在自己的项目中的时候进行一些修改和测试。 |
闂傚倸鍊搁崐鎼佸磹瀹勬噴褰掑炊椤掆偓杩濋梺閫炲苯澧撮柡灞剧〒閳ь剨缍嗛崑鍛暦瀹€鍕厸鐎光偓閳ь剟宕伴弽顓溾偓浣糕槈濡嘲鐗氶梺鍛婂姉閸嬫挸袙婢跺绻嗛柣鎰典簻閳ь剚鍨垮畷鏇㈠蓟閵夈儱鐎梺绉嗗嫷娈旈柦鍐枛閺岋綁寮崶銉㈠亾閳ь剟鏌涚€n偅灏柍钘夘槸閳诲秹顢樿缁ㄥジ鏌熸笟鍨鐎规洘鍎奸ˇ顕€鏌¢埀顒勬嚍閵夛絼绨婚梺鍝勬川閸嬬偤藟閻愮儤鍊垫慨妯煎亾鐎氾拷闂傚倸鍊搁崐鎼佸磹妞嬪海鐭嗗〒姘e亾妤犵偞鐗犻、鏇㈠Χ閸℃ぞ绮℃俊鐐€栭崝褏绮婚幋鐘差棜闁秆勵殕閻撴洟鏌熼柇锕€鐏遍柛銈咁儔閺屻倝寮堕幐搴′淮闂佸搫鏈粙鎴﹀煡婢跺ň鏋庨柟閭﹀枤閳诲繒绱撻崒姘偓椋庢媼閺屻儱鐤鹃柣妯款嚙閽冪喖鏌i弮鍌楁嫛闁轰礁绉电换婵囩節閸屾碍鐏撻梺鍝勬-閸樺ジ鈥旈崘顔嘉ч柛鎰╁妼婵兘姊洪悷鏉挎闁瑰嚖鎷�>>
正在阅读:Java中运行其它程序方法的实例详解Java中运行其它程序方法的实例详解
2005-08-30 10:04
出处:
责任编辑:moningfeng