Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/368.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从Java启动的进程取消阻止?_Java_Process - Fatal编程技术网

如何从Java启动的进程取消阻止?

如何从Java启动的进程取消阻止?,java,process,Java,Process,当从cmd行执行某些命令(比如“x”)时,我得到以下消息: “…按任意键继续…”。因此,它等待用户输入解除阻止 但是当我从java执行相同的命令('x')时: Process p = Runtime.getRuntime().exec(cmd, null, cmdDir); // here it blocks and cannot use outputstream to write somnething p.getOutputStream().write(..); 代码块 我试图在进程的输出流

当从cmd行执行某些命令(比如“x”)时,我得到以下消息: “…按任意键继续…”。因此,它等待用户输入解除阻止

但是当我从java执行相同的命令('x')时:

Process p = Runtime.getRuntime().exec(cmd, null, cmdDir);
// here it blocks and cannot use outputstream to write somnething
p.getOutputStream().write(..);
代码块

我试图在进程的输出流中写入一些内容,但是如果代码从未达到这一行,我该怎么做呢?

我认为(尽管不能确定)您谈论的是Windows而不是Unix

如果是这样的话,命令行进程可能实际上并不是在等待按下
stdin
上的键(或输入),而是执行与旧的DOS
kbhit()
函数等效的操作

好吧,没有办法让这个功能相信键盘是在没有按下按键的情况下被按下的

要测试此理论,请创建一个文本文件“input.txt”,其中包含一些空行,然后运行:

foo.exe < input.txt
foo.exe
这将显示您的程序是在等待stdin还是在等待其他东西。

我认为(尽管不能确定)您谈论的是Windows而不是Unix

如果是这样的话,命令行进程可能实际上并不是在等待按下
stdin
上的键(或输入),而是执行与旧的DOS
kbhit()
函数等效的操作

好吧,没有办法让这个功能相信键盘是在没有按下按键的情况下被按下的

要测试此理论,请创建一个文本文件“input.txt”,其中包含一些空行,然后运行:

foo.exe < input.txt
foo.exe

这将显示您的程序是否正在等待stdin或其他内容。

程序无法继续,因为它被阻止,需要用户输入


一个选项是在单独的线程中启动外部进程,或者使用共享进程p的线程,以便能够写入其流。

程序无法继续,因为它被阻止,需要用户输入


一个选项是在单独的线程中启动外部进程,或者使用共享进程p的线程,以便能够写入其流。

您应该同时读取子进程的输出流和错误流。这些流的缓冲区大小是有限的。如果其中一个缓冲区已满,子进程将阻塞。我想这就是你的情况

您应该同时读取子流程的输出流和错误流。这些流的缓冲区大小是有限的。如果其中一个缓冲区已满,子进程将阻塞。我想这就是你的情况

我认为推荐使用Java执行外部应用程序的方法是使用ProcessBuilder。代码看起来像

//Launch the program
ArrayList<String> command = new ArrayList<String>();
command.add(_program);
command.add(param1);
...
command.add(param1);

ProcessBuilder builder = new ProcessBuilder(command);
//Redirect error stream to output stream
builder.redirectErrorStream(true);

Process process = null;
BufferedReader br = null;
try{
    process = builder.start();

    InputStream is = process.getInputStream();
    br = new BufferedReader( new InputStreamReader(is));
    String line;

    while ((line = br.readLine()) != null) {
         log.add(line);
    }
}catch (IOException e){
    e.printStackTrace();
}finally{
    try{
        br.close();
    }catch (IOException e){
        e.printStackTrace();
    }
}
//启动程序
ArrayList命令=新建ArrayList();
添加(_程序);
添加命令(param1);
...
添加命令(param1);
ProcessBuilder=新的ProcessBuilder(命令);
//将错误流重定向到输出流
builder.redirectErrorStream(true);
Process=null;
BufferedReader br=null;
试一试{
process=builder.start();
InputStream=process.getInputStream();
br=新的BufferedReader(新的InputStreamReader(is));
弦线;
而((line=br.readLine())!=null){
log.add(行);
}
}捕获(IOE异常){
e、 printStackTrace();
}最后{
试一试{
br.close();
}捕获(IOE异常){
e、 printStackTrace();
}
}

process对象有一个get[Input/Output/Error]流,可用于与程序交互。

我认为推荐使用Java执行外部应用程序的方法是使用ProcessBuilder。代码看起来像

//Launch the program
ArrayList<String> command = new ArrayList<String>();
command.add(_program);
command.add(param1);
...
command.add(param1);

ProcessBuilder builder = new ProcessBuilder(command);
//Redirect error stream to output stream
builder.redirectErrorStream(true);

Process process = null;
BufferedReader br = null;
try{
    process = builder.start();

    InputStream is = process.getInputStream();
    br = new BufferedReader( new InputStreamReader(is));
    String line;

    while ((line = br.readLine()) != null) {
         log.add(line);
    }
}catch (IOException e){
    e.printStackTrace();
}finally{
    try{
        br.close();
    }catch (IOException e){
        e.printStackTrace();
    }
}
//启动程序
ArrayList命令=新建ArrayList();
添加(_程序);
添加命令(param1);
...
添加命令(param1);
ProcessBuilder=新的ProcessBuilder(命令);
//将错误流重定向到输出流
builder.redirectErrorStream(true);
Process=null;
BufferedReader br=null;
试一试{
process=builder.start();
InputStream=process.getInputStream();
br=新的BufferedReader(新的InputStreamReader(is));
弦线;
而((line=br.readLine())!=null){
log.add(行);
}
}捕获(IOE异常){
e、 printStackTrace();
}最后{
试一试{
br.close();
}捕获(IOE异常){
e、 printStackTrace();
}
}

process对象有一个get[Input/Output/Error]流,可用于与程序交互。

我在上写了一个命令行执行的答案

你的问题有点棘手,因为你可能需要回复

在您的情况下,可能需要为输入流gobbler提供类似于回复通道的内容:

 StreamGobbler outputGobbler = new StreamGobbler(
                                    proc.getInputStream(), "OUTPUT", 
                                    proc.getOutputStream());
并使其匹配给定输入流上的模式和应答

while ((line = br.readLine()) != null) {
    System.out.println(type + ">" + line);
    if (line.contains(PRESS_KEY_CONTINUE) {
        ostream.write("y".getBytes("US-ASCII")); 
        System.out.println("< y"); 
    }
}
while((line=br.readLine())!=null){
系统输出打印项次(类型+“>”+行);
如果(行包含)(按\键\继续){
ostream.write(“y”.getBytes(“US-ASCII”);
系统输出打印项次(“y”);
}
}

希望这有帮助。

我在上写了一个关于命令行执行的答案

你的问题有点棘手,因为你可能需要回复

在您的情况下,可能需要为输入流gobbler提供类似于回复通道的内容:

 StreamGobbler outputGobbler = new StreamGobbler(
                                    proc.getInputStream(), "OUTPUT", 
                                    proc.getOutputStream());
并使其匹配给定输入流上的模式和应答

while ((line = br.readLine()) != null) {
    System.out.println(type + ">" + line);
    if (line.contains(PRESS_KEY_CONTINUE) {
        ostream.write("y".getBytes("US-ASCII")); 
        System.out.println("< y"); 
    }
}
while((line=br.readLine())!=null){
系统输出打印项次(类型+“>”+行);
如果(行包含)(按\键\继续){
ostream.write(“y”.getBytes(“US-ASCII”);
系统输出打印项次(“y”);
}
}

希望这能有所帮助。

这是我解决这个问题的方法,灵感来自Alnitak的建议: 按如下方式运行命令:

Process p = Runtime.getRuntime().exec(cmd + " < c:\\someTextFile.txt", null, cmdDir);
...
int errCode = p.waitFor();
...
processp=Runtime.getRuntime().exec(cmd+“
“someTextFile.txt”可以通过编程方式创建