我正在尝试执行一个新流程,并从Java中的输入流中读取内容。我已经成功使用Runtime.getRuntime()。exec(String)来启动和接收来自多个进程的输入。但是,当我尝试在其他某些进程上使用exec时,输入流的read方法将阻塞,并且似乎没有输入。是什么原因导致其中某些过程的输入流为空?具体来说,我想知道为什么bash.exe没有输出任何内容。
我已经编写了一个JUnit测试用例来演示此问题:
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import junit.framework.TestCase;
public class TestExec extends TestCase {
public void testExec() throws IOException {
List<InputPrinter> threads = new ArrayList<InputPrinter>();
// Create a process for each of the commands and make sure that
// it outputs at least one line to its input stream.
threads.add(testExec("cmd"));
threads.add(testExec("java"));
threads.add(testExec("C:/cygwin/bin/vim-nox.exe"));
// These bottom two fail, even though executing these
// commands in cmd.exe results in immediate output
threads.add(testExec("javac"));
threads.add(testExec("C:/cygwin/bin/bash.exe"));
// Give the threads a second to execute
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
fail();
}
// Test that each command had input to read
for(InputPrinter ip : threads) {
assertTrue(ip.command + " has not read any input", ip.hasRead);
}
}
// Starts a process for the given command and returns an
// InputPrinter that can be used to check if the process
// has had an input to read.
public InputPrinter testExec(String command) throws IOException {
Process proc = Runtime.getRuntime().exec(command);
InputStream in = proc.getInputStream();
InputPrinter ip = new InputPrinter(in, command);
new Thread(ip).start();
return ip;
}
// Simple Runnable to read from an InputStream. hasRead will be
// true if at least one input has been read from the stream
private class InputPrinter implements Runnable {
InputStream in;
String command;
boolean hasRead;
public InputPrinter(InputStream in, String command) {
this.in = in;
this.command = command;
this.hasRead = false;
}
// Loop indefinitely while printing any received input
public void run() {
try {
final byte[] b = new byte[1024];
while (true) {
int n = in.read(b);
if (n > 0) {
System.out.print(new String(Arrays.copyOf(b, n)));
hasRead = true;
}
}
} catch (IOException e) {
e.printStackTrace();
fail();
}
}
}
}
编辑:
据我所知,如果程序未使用stdout或stderr,则Windows命令提示符下不会显示任何内容。启动bash进程时,我期望看到的是“ bash-3.2
$”,这与打开命令提示符并运行“ bash.exe”时看到的相同:
Microsoft Windows [Version 6.1.7600]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
C:\cygwin\bin>bash.exe
bash-3.2$
就Java而言,据我所知,仅当它作为脚本运行时,才可以通过管道将bash的输出(或输入)通过管道传递给bash,而不是当它作为交互式shell运行时(在这种情况下,只能将cmd参数传递给它)。
换句话说,如注释中所述,当您从cmd运行bash时,您会看到输出,但它包含在bash进程中,bash发送回父cmd进程不是输出。
关于javac进程,它实际上是将输出发送到错误流。尝试从CMD运行javac 1>null
和javac 2>null
,你会看到其中的差别。
您看过这里的api
吗?您可以尝试使用ProcessBuilder并将错误流重定向回主要输入流,以这种方式处理流程会容易得多。
问题内容: 仅当数据库名称包含(新数据库(myid)等)时,我才能读取文件。我给出以下示例代码: 假设我的数据库名称de mo是指我在打印行时得到的数据库名称仅是de。数据库名称带有空白时可以吗? 问题答案: 您熟悉双引号错误吗?(用于或) 你可以试试: 只需确保您不必传递的任何参数都包含双引号( 而不 是以双引号开头) (请参见 错误6511002 ) 任何类似的参数: 将在 内部 (通过实现)
问题内容: 我有一个程序Test.java: 应该将HelloWorld1和HelloWorld2打印到文件text.txt中。但是,当我查看文件时,只能看到HelloWorld1。 HelloWorld2去了哪里?它消失在稀薄的空气中了吗? 可以说我也想将HelloWorld2重定向到test.txt。我不能仅在命令中添加“ >> test.txt”,因为会出现文件已打开错误。那么我该怎么做呢?
问题内容: 我正在执行一个命令,该命令向我返回文件的修订号;’文档名称’。但是,如果执行命令时遇到问题,则应用程序将挂断。我该怎么做才能避免这种情况?请在下面找到我的代码。 问题答案: 我想问题是您只在读取InputStream而没有在读取ErrorStream。您还必须注意并行读取两个流。可能发生这种情况,当前从输出流中管道传输的数据已填满OS缓冲区,您的exec命令将自动挂起,以使您的阅读器有
我需要检查为什么exec函数停止我的php脚本。 我在HTTP查询中调用了“exec”函数中的bat文件(但我遇到了passthru、system和proc_open的问题),2分钟后我得到了一个错误代码500(没有详细信息)。但是我的bat文件总是在后台运行(我可以看到创建的文件…)我是这样使用它的: 在$输出中我什么都得不到,在phperror_log什么都没有...我添加了以下参数: 同样的
问题内容: 我正在尝试通过使用删除垃圾文件 只要我不使用通配符,它就可以正常工作,即,这有效: 而以下内容返回“没有此类文件或目录”: 我应该能够做到这里概述的所有美好的事情,对吗? 问题答案: 我可能建议您让Java为您执行此操作? 使用file.listFiles()获取文件列表 如果需要,使用file.getName()。contains(string)对其进行过滤 遍历执行file.d
问题内容: 此代码将执行一个外部exe应用程序。 如果我想执行外部Java文件怎么办?可能吗?例如以下命令: 该代码在java和cmd提示符下不起作用。如何解决呢? 问题答案: 首先,您的命令行看起来不正确。执行命令与批处理文件不同,它不会执行一系列命令,而只会执行一个命令。 从外观上看,您正在尝试更改要执行的命令的工作目录。一个更简单的解决方案是使用,它将允许您指定给定命令的起始目录… 例如…