编写标准输入并等待标准输出

时间:2009-10-28 16:15:36

标签: java process input standards

我正在尝试创建一个让netsh windows命令行工具保持打开状态的Thread,这样我就可以执行netsh命令而不必每次都打开它。

问题是,一旦我创建了Thread,只需要第一个命令调用......后续调用似乎没有效果。

这是我的代码:

public class NetshThread implements Runnable{
 private static Process netshProcess = null;
 private static BufferedInputStream netshInStream = null;
 private static BufferedOutputStream netshOutStream = null;
 public BufferedReader inPipe = null;

 public void run(){
  startNetsh();
 }

 public void startNetsh(){
  try {
   netshProcess = Runtime.getRuntime().exec("netsh");
   netshInStream = new BufferedInputStream(netshProcess.getInputStream());
   netshOutStream =  new BufferedOutputStream(netshProcess.getOutputStream());
   inPipe = new BufferedReader(new InputStreamReader(netshInStream));
  } catch (IOException e) {
   e.printStackTrace();
  }
 } 

 public void executeCommand(String command){
  System.out.println("Executing: " + command);
  try {
   String str = "";
   netshOutStream.write(command.getBytes());
   netshOutStream.close();
   while ((str = inPipe.readLine()) != null) {
                System.out.println(str);
            }
  } catch (IOException e) {
   e.printStackTrace();
  }
 }
 public void closeNetsh(){
  executeCommand("exit");
 }

 public static void main(String[] args){
  NetshThread nthread = new NetshThread();
  nthread.run();
  String command = "int ip set address " +
    "\"Local Area Connection 6\" static .69.69.69 255.255.255.0";
  nthread.executeCommand(command);
  command = "int ip set address " +
    "\"Local Area Connection 6\" static 69.69.69.69 255.255.255.0";
  nthread.executeCommand(command);
  System.out.println("*** DONE ***");
 }
}

谢谢!!! =)

更新1:

好的......我现在正在使用PrintWriter ...所以我认为我不需要再刷新任何东西了,因为构造函数是:

new PrintWriter(netshOutStream,true); (就像Shiny先生告诉我的那样)......

假设我决定在第一个输出行可用时断开while循环...我也不工作......下一个命令不会被执行....我的代码现在看起来像:

import java.io.*;

public class NetshThread implements Runnable{
    private static Process netshProcess = null;
    private static BufferedInputStream netshInStream = null;
    private static BufferedOutputStream netshOutStream = null;
    public BufferedReader inPipe = null;
    private PrintWriter netshWriter = null;

    public void run(){
        startNetsh();       
    }

    public void startNetsh(){
        try {
            netshProcess = Runtime.getRuntime().exec("netsh");
            netshInStream = new BufferedInputStream(netshProcess.getInputStream());
            netshOutStream =  new BufferedOutputStream(netshProcess.getOutputStream());
            netshWriter = new PrintWriter(netshOutStream, true);
            inPipe = new BufferedReader(new InputStreamReader(netshInStream));
        } catch (IOException e) {
            e.printStackTrace();
        }
    } 

    public void executeCommand(String command){
        System.out.println("Executing: " + command);
        try {
            String str = "";
            netshWriter.println(command);
            while ((str = inPipe.readLine()) != null) {
                System.out.println(str);
                break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public void closeNetsh(){
        executeCommand("exit");
    }

    public static void main(String[] args){     
        NetshThread nthread = new NetshThread();
        Thread xs = new Thread(nthread);
        xs.run();
        String command = "int ip set address " +
                "\"Local Area Connection 6\" static .69.69.69 255.255.255.0";
        nthread.executeCommand(command);
        command = "int ip set address " +
                "\"Local Area Connection 6\" static 69.69.69.69 255.255.255.0";
        nthread.executeCommand(command);
        System.out.println("*** DONE ***");
    }
}

和我得到的输出:

  

执行:int ip set address“Local   区域连接6“静态.69.69.69   对于addr,255.255.255.0 netsh> .69.69.69不是可接受的值。   执行:int ip set address“Local   区域连接6“静态69.69.69.69

为什么不执行第二个命令???

  

255.255.255.0

     

*完成*

更新2:

在教师在西班牙语窗口环境中尝试我的应用程序之前,一切似乎都运行良好....

我的代码如下:

Scanner fi = new Scanner(netshProcess.getInputStream());

public void executeCommand(String command) {
        System.out.println("Executing: " + command);
        String str = "";
        netshWriter.println(command);
        fi.skip("\\s*");
        str = fi.nextLine();
        System.out.println(str);
}

我需要的是以某种方式将netshWriter编码设置为Windows默认值。

谁能知道该怎么做?

6 个答案:

答案 0 :(得分:3)

您正在关闭输出流。

答案 1 :(得分:2)

您需要将流处理移动到单独的线程中。发生的事情是 inPipe.readLine()阻止等待netsh返回数据。 Apache有一个处理进程处理的包。我会考虑使用它而不是滚动你自己的(http://commons.apache.org/exec/

答案 2 :(得分:1)

这在很多方面都是错误的。

首先,为什么一个Runnable对象?这在任何地方都没有传递给Thread。您创建的唯一线程不是java线程,它是由exec()创建的OS进程。

其次,您需要一种方法来了解何时完成netsh。读取netsh输出的循环将永远运行,因为当netsh关闭其标准输出时,readLine将仅返回null(在您的情况下永远不会)。在处理完请求时,您需要查找netsh打印的标准内容。

正如其他人所说,关闭是坏事。使用同花顺。希望netsh使用同花顺回复你......

答案 3 :(得分:0)

您确实需要删除close,否则您永远无法执行其他命令。当删除close()调用后说“它将无法工作”时,是否意味着没有命令被处理?

有可能在您发送命令的字节后,您需要发送某种确认密钥以启动进程,然后处理它。如果你通常从键盘输入它,它可能就像回车一样简单,否则它可能需要是Ctrl-D或类似的。

我尝试用

替换close()行
netshOutStream.write('\n');

看看是否有效。根据软件的不同,您可能需要更改发送的字符以表示命令的结束,但这种一般方法应该可以帮助您完成。

编辑:

调用

也是明智的
netshOutStream.flush();

以上几行之后;如果没有刷新,则无法保证您的数据将被写入,实际上,因为您正在使用BufferedInputStream,我99%确定在刷新流之前不会写入任何 。因此,为什么后面的代码会阻塞,因为你正在等待响应,而进程还没有看到任何输入,并且正在等待发送一些。

答案 4 :(得分:0)

我试试:

PrintWriter netshWriter = new PrintWriter(netshOutputStream, true); // auto-flush writer

netshWriter.println(command);

没有关闭()流,自动刷新流,并使用编写器发送字符数据,而不是依赖平台“本机字符集”。

答案 5 :(得分:0)

我使用的是扫描仪而不是BufferedReader,因为我喜欢它。所以这段代码有效:

Scanner fi = new Scanner(netshProcess.getInputStream());


public void executeCommand(String command) {
    System.out.println("Executing: " + command);
    String str = "";
    netshWriter.println(command);
    fi.skip("\\s*");
    str = fi.nextLine();
    System.out.println(str);
}

它执行两个命令。