IOException:error = 7,带有大命令行的参数列表太长

时间:2013-06-04 07:27:56

标签: java unix process

我需要从Java调用Unix命令。代码如下。

String strCmd = "iconv -f "+ strSrcEncoding+" -t "+ strTgtEncoding + " <<< "+"\""+InputMessage+"\"";

String commands[] = {"bash","-c",strCmd};
Process proc = Runtime.getRuntime().exec(commands);
String strData = null;

// Get the error Stream
BufferedReader brStdError = new BufferedReader(new
        InputStreamReader(proc.getErrorStream()));
StringBuilder sbError = new StringBuilder();


// read any errors from the attempted command
while ((strData = brStdError.readLine()) != null) {
    sbError.append(strData);
}

if(sbError.toString().isEmpty())
    return "success";
else
    return "failure"+sbError.toString();

当我传递大数据时出现错误

"bash": java.io.IOException: error=7, Argument list too long

我尝试使用echo代替

echo <<InputMessage>> | iconv -f utf8 -t Cp930

但是得到了同样的错误

我错过了什么吗?

3 个答案:

答案 0 :(得分:3)

您可以在命令行上传递给程序的数据有限。如果您有大量数据,则应使用其标准输入流将其传递给iconv,即将其写入proc.getOutputStream。这是一个例子:

OutputStream os = proc.getOutputStream();
os.write(InputMessage.getBytes(strSrcEncoding));
os.close();

不幸的是,对于更长的消息,这也会失败,因为iconv将填充它所连接的管道的缓冲区,并等待管道被读取。解决方案是将数据从一个线程写入iconv并从另一个线程读取输出。由于所有这些陷阱,处理外部过程是一件麻烦事。你可以在这里阅读更多相关信息:http://www.javaworld.com/jw-12-2000/jw-1229-traps.html Apache commons exec可以帮助你处理其中一些问题。

另一方面,你为什么使用iconv?您知道Java对大多数字符编码都有很好的库支持,包括cp930吗?

答案 1 :(得分:2)

当参数的大小超过允许的大小时,会发生这种情况。这取决于平台。

要验证最大限制,请运行

this.props.fields.MYFIELD.onChange(CHILDLOCALSTATE)

对于mac osx环境,我可以看到262144是限制。

每个平台的限制是不同的,可以在这里找到: http://www.in-ulm.de/~mascheck/various/argmax/

检查环境字符串:

$ getconf ARG_MAX

答案 2 :(得分:0)

我在尝试按如下方式设置环境变量时遇到了这个问题:

final ProcessBuilder pb = new ProcessBuilder(...);
pb.environment().putAll(env); //here it's ok
...
pb.start(); //here is where it throws the exception

问题在于env地图包含的内容,尽管"bash":java.io.IOException: error=7, Argument list too long表示不同。