错误安装 调用 java vm(sysexec) 错误_如何解决调用Runtime#exec()的“ java.io.IOException:错误= 12...

在我的系统上,我无法运行启动流程的简单Java应用程序。我不知道该怎么解决。

您能给我一些解决方法的提示吗?

该程序是:

[root@newton sisma-acquirer]# cat prova.java

import java.io.IOException;

public class prova {

public static void main(String[] args) throws IOException {

Runtime.getRuntime().exec("ls");

}

}

结果是:

[root@newton sisma-acquirer]# javac prova.java && java -cp . prova

Exception in thread "main" java.io.IOException: Cannot run program "ls": java.io.IOException: error=12, Cannot allocate memory

at java.lang.ProcessBuilder.start(ProcessBuilder.java:474)

at java.lang.Runtime.exec(Runtime.java:610)

at java.lang.Runtime.exec(Runtime.java:448)

at java.lang.Runtime.exec(Runtime.java:345)

at prova.main(prova.java:6)

Caused by: java.io.IOException: java.io.IOException: error=12, Cannot allocate memory

at java.lang.UNIXProcess.(UNIXProcess.java:164)

at java.lang.ProcessImpl.start(ProcessImpl.java:81)

at java.lang.ProcessBuilder.start(ProcessBuilder.java:467)

... 4 more

系统配置:

[root@newton sisma-acquirer]# java -version

java version "1.6.0_0"

OpenJDK Runtime Environment (IcedTea6 1.5) (fedora-18.b16.fc10-i386)

OpenJDK Client VM (build 14.0-b15, mixed mode)

[root@newton sisma-acquirer]# cat /etc/fedora-release

Fedora release 10 (Cambridge)

编辑:解决方案 这解决了我的问题,我不知道为什么:

回声0> / proc / sys / vm / overcommit_memory

谁能解释的投票:)

附加信息,顶部输出:

top - 13:35:38 up 40 min,  2 users,  load average: 0.43, 0.19, 0.12

Tasks: 129 total,   1 running, 128 sleeping,   0 stopped,   0 zombie

Cpu(s):  1.5%us,  0.5%sy,  0.0%ni, 94.8%id,  3.2%wa,  0.0%hi,  0.0%si,  0.0%st

Mem:   1033456k total,   587672k used,   445784k free,    51672k buffers

Swap:  2031608k total,        0k used,  2031608k free,   188108k cached

附加信息,免费输出:

[root@newton sisma-acquirer]# free

total       used       free     shared    buffers     cached

Mem:       1033456     588548     444908          0      51704     188292

-/+ buffers/cache:     348552     684904

Swap:      2031608          0    2031608

<think>我们正在解决Java调用Python脚本时出现的CreateProcess error=206错误,该错误表示文件名或扩展名太长。 解决方案思路: 1. 使用ProcessBuilder替代Runtime.exec,因为ProcessBuilder可以更好地处理长命令和参数。 2. 将命令和参数放入列表,避免在单个字符串中处理导致长度问题。 3. 考虑将长参数写入临时文件,然后通过文件传递参数。 4. 使用脚本封装,将长命令放入一个脚本文件中,然后执行该脚本。 根据用户提供的引用[2],我们知道在调用外部程序时,系统需要找到可执行文件(这里是python),如果路径中有空格,可能需要用双引号包围,但使用列表形式传递参数可以避免这个问题。 具体步骤: 方法一:使用ProcessBuilder 将命令分解为多个部分,例如: ProcessBuilder pb = new ProcessBuilder("python", "path/to/script.py", arg1, arg2, ...); 这样系统会将这些参数作为数组传递,而不是一个长字符串,从而避免命令行长度限制。 方法二:如果参数太多导致整个命令行仍然过长,可以将参数写入一个临时文件,然后在Python脚本中读取该文件。 方法三:使用一个批处理文件(Windows)或shell脚本(Linux)来执行Python脚本,并在其中设置参数,然后Java调用这个脚本。 下面我们分别给出示例: 方法一示例代码: ```java try { ProcessBuilder pb = new ProcessBuilder("python", "C:/path/to/your/script.py", "arg1", "arg2", ...); // 注意:参数数量多时可能仍然超长 Process p = pb.start(); // 读取输出和错误流 BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream())); String line; while ((line = reader.readLine()) != null) { System.out.println(line); } int exitCode = p.waitFor(); System.out.println("Exited with code: " + exitCode); } catch (Exception e) { e.printStackTrace(); } ``` 方法二:使用临时文件传递参数 步骤: 1.Java中将参数写入一个临时文件(例如JSON格式)。 2. 修改Python脚本,使其从该临时文件中读取参数。 3. 执行Python脚本时,只传递临时文件路径作为参数。 Java端: ```java // 创建临时文件 File tempFile = File.createTempFile("args", ".json"); // 将参数写入文件(例如使用JSON) // 假设参数是一个列表 List<String> params = ...; // 你的参数列表 ObjectMapper mapper = new ObjectMapper(); // 使用Jackson库,需要引入依赖 mapper.writeValue(tempFile, params); // 使用ProcessBuilder执行 ProcessBuilder pb = new ProcessBuilder("python", "C:/path/to/script.py", tempFile.getAbsolutePath()); Process p = pb.start(); ... // 同上,处理输出和等待 ``` Python脚本端(script.py): ```python import sys import json if __name__ == '__main__': with open(sys.argv[1]) as f: args = json.load(f) # 使用args列表中的参数 ``` 方法三:编写一个包装脚本(以Windows批处理为例) 创建一个批处理文件run_script.bat: @echo off python C:/path/to/your/script.py %* 然后在Java调用这个批处理文件,并传递参数(注意,批处理文件可以接受长参数,但实际参数长度限制仍然存在,不过批处理文件内部可以处理多个参数,不会将所有参数拼接成一个字符串传递) 但是,这种方法可能并不能解决长参数列表的问题,因为最终命令行还是由批处理文件传递给python,所以如果参数非常多,还是可能超过限制。 因此,推荐方法二:通过临时文件传递参数。 另外,注意错误206(ERROR_FILENAME_EXCED_RANGE)在Windows系统上的命令行长度限制是32767个字符。如果单个参数字符串太长(比如一个很长的字符串作为参数),那么即使只有一个参数,也可能超过限制。此时,只能通过临时文件传递。 总结: 对于长参数列表或长字符串参数,使用临时文件传递是最可靠的方法。 相关问题: 1.Java调用外部程序时,除了使用Runtime.exec,还有哪些方式? 2. 如何确保Java调用的Python脚本在跨平台时(Windows/Linux)都能正常运行? 3. 如何处理Java调用外部脚本时的错误流和输出流,避免进程阻塞? 注意:在方法二中,我们使用了Jackson库来写JSON,如果项目中没有,可以使用其他方式(如Gson)或者手动构造JSON字符串(不推荐)。也可以使用简单的格式,例如每行一个参数,然后Python按行读取。 如果不想引入额外依赖,可以使用Java标准库写临时文件: ```java List<String> params = ...; // 参数列表 Path tempFile = Files.createTempFile("args", ".txt"); Files.write(tempFile, params, StandardCharsets.UTF_8); // 每个参数一行 ``` 然后Python脚本中: ```python with open(sys.argv[1], 'r') as f: params = [line.strip() for line in f] ``` 这样也可以避免引入JSON解析,但要注意参数中如果有换行符会被破坏,所以如果参数包含换行符,则不能使用这种方法。此时建议使用JSON格式。</think>### Java调用Python脚本报错 CreateProcess error=206 解决方案 当使用 `Runtime.getRuntime().exec()` 执行长命令时,Windows系统会因**命令行长度超过32767字符限制**而触发`CreateProcess error=206`错误(文件名或扩展名太长)。以下是三种解决方案: --- #### 方案1:使用 `ProcessBuilder` 拆分参数(推荐) ```java ProcessBuilder pb = new ProcessBuilder( "python", "C:/path/to/your_script.py", "arg1", "arg2", // 更多参数... "argN" ); pb.redirectErrorStream(true); // 合并错误流和输出流 Process process = pb.start(); // 读取输出 try (BufferedReader reader = new BufferedReader( new InputStreamReader(process.getInputStream()))) { String line; while ((line = reader.readLine()) != null) { System.out.println(line); } } int exitCode = process.waitFor(); ``` **原理**:将命令分解为字符串数组,避免单字符串长度超标[^1]。 --- #### 方案2:通过临时文件传递长参数 ```java // Java端:写入参数到临时文件 Path argFile = Files.createTempFile("args", ".txt"); Files.write(argFile, longParamString.getBytes(StandardCharsets.UTF_8)); // 执行Python脚本并传递文件路径 Process p = Runtime.getRuntime().exec( "python C:/path/to/script.py " + argFile.toString() ); ``` ```python # Python端:读取参数文件 import sys with open(sys.argv[1], 'r') as f: long_param = f.read() ``` **优势**:规避命令行长度限制,适合处理超长JSON/XML等数据[^2]。 --- #### 方案3:封装为批处理脚本(Windows) 创建 `run_script.bat`: ```bat @echo off python C:\path\to\your_script.py %* ``` Java调用批处理: ```java Runtime.getRuntime().exec("cmd /c run_script.bat arg1 arg2 ..."); ``` **适用场景**:参数结构复杂但长度可控时。 --- ### 关键注意事项 1. **路径规范**: - 使用短路径(`C:\PROGRA~1\` 替代 `C:\Program Files\`) - 避免空格:`"C:/Project/script.py"` → `"C:/Projec~1/script.py"` 2. **流处理**: ```java // 必须消费输入/错误流,防止进程阻塞 new Thread(() -> { try (BufferedReader err = new BufferedReader( new InputStreamReader(process.getErrorStream()))) { while (err.readLine() != null); } catch (IOException e) { /*...*/ } }).start(); ``` 3. **跨平台兼容**: ```java String os = System.getProperty("os.name").toLowerCase(); String cmd = os.contains("win") ? "python.exe" : "python3"; ``` > **引用说明**:`CreateProcess`错误源于Windows API限制[^1],而Python的脚本执行特性允许通过文件传递参数[^2]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值