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

Java 写入标准输入并等待标准输出,java,process,input,standards,Java,Process,Input,Standards,我试图创建一个线程,使netsh windows命令行工具保持打开状态,这样我就可以执行netsh命令,而不必每次都打开它 问题是,一旦我创建了线程,第一个命令调用就可以了。。。随后的电话似乎没有效果 这是我的密码: public class NetshThread implements Runnable{ private static Process netshProcess = null; private static BufferedInputStream netshInStream

我试图创建一个线程,使netsh windows命令行工具保持打开状态,这样我就可以执行netsh命令,而不必每次都打开它

问题是,一旦我创建了线程,第一个命令调用就可以了。。。随后的电话似乎没有效果

这是我的密码:

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(netshOutStream,true);(就像Shinny先生告诉我的)

假设我决定在第一个输出行可用时中断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“本地 区域连接6“静态。69.69.69 255.255.255.0 netsh>.69.69.69不是addr的可接受值。 正在执行:int ip set address“本地 区域连接6“静态69.69.69

为什么不执行第二个命令

255.255.255.0

*完成*

更新2: 在一位老师在西班牙windows环境下试用我的应用程序之前,一切似乎都很正常

我的代码如下所示:

Scanner fi=新扫描仪(netshProcess.getInputStream())

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


有人知道该由谁来执行此操作吗?

您正在关闭输出流。

您正在关闭输出流。

您确实需要删除
关闭
,否则您将无法执行其他命令。删除close()调用后,如果说“它不会工作”,是否意味着不处理任何命令

很有可能,在您发送命令的字节后,您需要发送某种类型的确认密钥,以便进程开始处理它。如果您通常从键盘输入,它可能像回车一样简单,否则可能需要Ctrl-d或类似的字符

我会尝试将close()行替换为

netshOutStream.write('\n');
看看这是否有效。根据软件的不同,您可能需要更改发送的字符以表示命令的结束,但这种通用方法应该可以帮助您完成

编辑:

打电话也是明智之举

netshOutStream.flush();

在上述行之后;如果没有刷新,就不能保证您的数据会被写入,事实上,由于您使用的是BufferedInputStream,我99%确定在刷新流之前不会写入任何内容。因此,为什么代码随后会阻塞,因为您正在等待响应,而进程尚未看到任何输入,并且正在等待您发送一些输入。

您确实需要删除
close
,否则您将永远无法执行另一个命令。删除close()调用后,如果说“它不会工作”,是否意味着不处理任何命令

很有可能,在您发送命令的字节后,您需要发送某种类型的确认密钥,以便进程开始处理它。如果您通常从键盘输入,它可能像回车一样简单,否则可能需要Ctrl-d或类似的字符

我会尝试将close()行替换为

netshOutStream.write('\n');
看看这是否有效。根据软件的不同,您可能需要更改发送的字符以表示命令的结束,但这种通用方法应该可以帮助您完成

编辑:

打电话也是明智之举

netshOutStream.flush();
在上述行之后;如果没有刷新,就不能保证您的数据会被写入,事实上,由于您使用的是BufferedInputStream,我99%确定在刷新流之前不会写入任何内容。因此,当您正在等待响应,而进程尚未看到任何输入,并且正在等待您发送一些输入时,为什么代码随后会阻塞。

我会尝试:

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

netshWriter.println(command);
无需关闭()流,自动刷新流,并使用写入程序发送字符数据,而不依赖平台“本机字符集”。

我会尝试:

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

netshWriter.println(command);

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

这在许多方面似乎是错误的

首先,为什么是可运行对象?这永远不会传递到任何地方的线程。您正在创建的唯一线程不是java线程,而是由exec()创建的OS进程

其次,您需要一种知道netsh何时完成的方法。读取netsh输出的循环将永远运行,因为只有当netsh关闭其标准时,readLine才会返回null(在您的例子中,这永远不会)。您需要寻找netsh在处理完您的请求后打印的一些标准内容


正如其他人提到的,亲密是不好的。使用冲水器。希望netsh使用冲水回你…

这在许多方面似乎是错误的

首先,为什么是可运行对象?这永远不会传递到任何地方的线程。您正在创建的唯一线程不是java线程,而是由exec()创建的OS进程

其次,您需要一种知道netsh何时完成的方法。读取netsh输出的循环将永远运行,因为只有当netsh关闭其标准时,readLine才会返回null(在您的例子中,这永远不会)。您需要寻找netsh在处理完您的请求后打印的一些标准内容


正如其他人提到的,亲密是不好的。使用冲水器。希望netsh使用刷新返回给您…

您需要将流处理移动到单独的线程中。发生的情况是,inPipe.readLine()正在阻塞等待netsh返回数据。Apache有一个处理进程处理的包。我将考虑使用它,而不是滚动您自己的()

您需要将流处理移动到单独的线程中。发生了什么事