为什么通过java程序调用命令行实用程序时挂起?
在接下来的任务中,我需要你们的建议和指导。 我正在使用libdmtx,它附带一个命令行实用程序,用于读取ECC200数据矩阵条形码的图像文件,读取其内容,并将解码后的消息写入标准输出。 我想在linux平台上的java程序中使用这个命令行实用程序。我使用ubuntu linux。我已经在我的linux机器上安装了libdmtx。当我调用命令时 dmtxread-n/home/admin/ab.tif 在linux终端上,它立即给出图像中条形码的解码值 当我要使用java程序调用这个命令时,代码会在命令执行过程中停顿,dotn会给出输出。 看起来程序正在处理或挂起 下面是调用以下命令的java代码为什么通过java程序调用命令行实用程序时挂起?,java,linux,barcode-scanner,runtime.exec,processbuilder,Java,Linux,Barcode Scanner,Runtime.exec,Processbuilder,在接下来的任务中,我需要你们的建议和指导。 我正在使用libdmtx,它附带一个命令行实用程序,用于读取ECC200数据矩阵条形码的图像文件,读取其内容,并将解码后的消息写入标准输出。 我想在linux平台上的java程序中使用这个命令行实用程序。我使用ubuntu linux。我已经在我的linux机器上安装了libdmtx。当我调用命令时 dmtxread-n/home/admin/ab.tif 在linux终端上,它立即给出图像中条形码的解码值 当我要使用java程序调用这个命令时,代码会
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
public class Classtest {
public static void getCodes(){
try
{
Process p;
String command[]=new String[3];
command[0]="dmtxread";
command[1]="-n";
command[2]="/home/admin/ab.tif";
System.out.println("Command : "+command[0]+command[1]+command[2]);
p=Runtime.getRuntime().exec(command); //I think hangs over here.
BufferedReader reader=new BufferedReader(new InputStreamReader(p.getErrorStream()));
String line=reader.readLine();
if(line==null){
reader=new BufferedReader(new InputStreamReader(p.getInputStream()));
line=reader.readLine();
System.out.print("Decoded :- "+line);
}else{
System.out.print("Error :- "+line);
}
System.out.println(p.waitFor());
}catch(IOException e1) {
e1.getMessage();
e1.printStackTrace();
}catch(InterruptedException e2) {
e2.getMessage();
e2.printStackTrace();
}
}
public static void main(String args[]){
getCodes();
}
}
请告诉我的朋友我的代码哪里出错了
我参考了下面的文章,但没有得到任何帮助
请引导我的朋友们!
谢谢大家!
这是我使用ProcessBuilder类的新代码,该代码还提供了与上面代码相同的输出,即挂起在第行
Process进程=pb.start()
公共类测试{
公共静态void main(最终字符串[]args)引发IOException、InterruptedException{
//生成命令
List命令=new ArrayList();
命令。添加(“dmtxread”);
命令。添加(“-n”);
commands.add(“/home/admin/ab.tif”);
System.out.println(命令);
//在目标上运行宏
ProcessBuilder pb=新的ProcessBuilder(命令);
pb.重定向错误流(真);
Process进程=pb.start();
//读取输出
StringBuilder out=新的StringBuilder();
BufferedReader br=新的BufferedReader(新的InputStreamReader(process.getInputStream());
String line=null,previous=null;
而((line=br.readLine())!=null){
系统输出打印项次(行);
}
//检查结果
if(process.waitFor()==0)
System.out.println(“成功!”);
系统出口(0);
//异常终止:记录命令参数、输出和抛出ExecutionException
System.err.println(命令);
System.err.println(out.toString());
系统出口(1);
}
}
请指导我解决这个问题。
谢谢你 我不确定您的程序到底发生了什么,它挂起在哪里(您可以使用调试器或跟踪输出来检查),但下面是可能的情况: 假设程序想要输出两行文本。或者只有一行,但进入标准。代码只从标准输出读取1行,然后等待进程退出。这意味着子程序可能会等待读卡器读取下一行,因此它会在
write
中等待,直到有人解锁管道——永远
当您从命令行运行
dmtxread
时,输出管道上没有阻塞,因此程序运行良好。您的流消耗代码非常混乱。您尝试从stderr读取一行,然后放弃该读卡器,然后尝试从stdout读取一行
waitFor
处被阻塞您链接的那篇文章详细介绍了使用流程输出流的正确方法。接受这个建议,没有人能给你比这个更好的建议。读线会阻塞,直到它从错误流接收到新行。因此,如果没有输出,程序将无法通过第一条读线 为简单起见,我建议您使用
ProcessBuilder
而不是Runtime.exec()
,它允许您按如下方式合并两个输入流:
ProcessBuilder builder = new ProcessBuilder(cmd,arg0,arg1);
builder.redirectErrorStream(true);
Process process = builder.start();
所以,现在你可以从其中一个读出来
或者,您可以使用单独的线程来使用这两个输入流
希望对您有所帮助谢谢您的回复,先生。我将按照您在我的代码中的建议进行更改,并让您知道结果。请检查我在上面问题底部添加的代码,该代码实现了您给出的解决方案,但仍然没有结果。嗯,现在看起来不错。有两件事需要尝试:1)使用您的程序运行类似于
ls
的命令。有输出吗?2) 注释掉整个while
块,看看它是否到达waitFor。3) 使用调试器一步一步地进行调试,看看它能走多远(或者如果您不知道如何做到这一点,只需在每行之间打印一些内容)当我执行问题中的第二个代码时,其行为与第一个代码相同,但经过很长时间后,它给了我一个我想要的输出,但现在的问题是扫描一张图像上的条形码所用的时间。谢谢先生的回复!正如您所建议的,我已经根据参考链接对代码进行了更改,我添加了streamgobbler类,作者在文章的第四页中添加了该类,并尝试运行该程序,但它没有在System.out.println(“命令:”)中打印任何内容;从您发布的代码中可以看出,您是如何得出代码阻塞在哪一行的结论的。请给出一些令人信服的证据,证明你的代码确实在那一行阻塞。当我执行我问题中的第二个代码时,它的行为与第一个代码相同,但经过很长时间后,它给了我一个我想要的输出,但现在的问题是代码扫描一幅图像上的条形码所花费的时间。谢谢你,先生回复正如您所建议的,我签入代码,但它既没有给出任何错误,也没有给出任何输出。@Param Ganak:那么可能reader.readLine()
永远挂起,等待程序输出一些东西?我真的不知道程序哪里出了问题,我在
ProcessBuilder builder = new ProcessBuilder(cmd,arg0,arg1);
builder.redirectErrorStream(true);
Process process = builder.start();