首页 > 解决方案 > 从java程序运行位于特定文件夹中的.exe并读取其输出

问题描述

我试图从我编写的 java GUI 运行 Yolo 检测器。我可以像这样使用 windows cmd 启动检测器:

cd <pathToYolo> \\ In my case named :C:\\AI\\Yolo_v4\\darknet\\build\\darknet\\x64
darknet.exe detetctor test <pathToAConfigFile> <pathToAnotherConfigFile> <pathToModelDef> -dont_show <pathToImage> 

我尝试了多种方法。我像这样使用 Runtime.getRuntime().exec() 。

try {

            String command = "darknet.exe detector test data\\obj.data cfg\\yolov4-obj.cfg backup\\rgbmodel\\yolov4-obj_last.weights -dont_show C:\\Users\\felix\\Desktop\\yoloTestSet\\RGBTest\\IMG_2392.jpg";
            Process proc = Runtime.getRuntime().exec("cmd /c start /wait " + command, null,
                    new File("C:\\AI\\Yolo_v4\\darknet\\build\\darknet\\x64"));
            
            BufferedReader br = new BufferedReader(
                    new InputStreamReader(proc.getInputStream()));
                String line;
                while ((line = br.readLine()) != null)
                    System.out.println(line);

            proc.waitFor();
            

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

我也试过:

        ProcessBuilder pb = new ProcessBuilder(
                "cmd",
                "/C",
                "start",
                "darknet.exe",
                "detector",
                "test",
                "data\\obj.data",
                "cfg\\yolov4-obj.cfg",
                "backup\\rgbmodel\\yolov4-obj_last.weights",
                "-dont_show",
                "-ext_output",
                "C:\\Users\\felix\\Desktop\\yoloTestSet\\RGBTest\\IMG_2392.jpg"
                
                );
        
        pb.directory(new File("C:\\AI\\Yolo_v4\\darknet\\build\\darknet\\x64"));
        
        try {
            Process process  = pb.start();
             InputStreamReader inputStreamReader = new InputStreamReader(process.getInputStream());
                BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
                String output = null;
                while ((output = bufferedReader.readLine()) != null) {
                    System.out.println(output);
                }
         
                //wait for the process to complete
                //process.waitFor();
         
                //close the resources
                //bufferedReader.close();
                process.destroy();
        } catch (IOException e) {
            e.printStackTrace();
        }

两者都将运行该过程并在 cmd 上打印所需的输出,然后关闭 cmd。到目前为止,这正是我想要的。我现在的问题是,如何正确读取此输出。

br.readLine() 

似乎为空。如果我在实际命令之前留下“开始”,我可以读取输出的第一行,然后一切都卡住了,省略“cmd”会给我这个错误:

Cannot run program "darknet.exe" (in directory "C:\AI\Yolo_v4\darknet\build\darknet\x64"): CreateProcess error=2, The system cannot find the file specified

doku 对“cmd /C start”部分的实际作用有点短。关于这里的问题以及如何正确地做到这一点,我会很感激一些建议,关于 Felix

标签: java

解决方案


感谢 Daniel Junglas 的提示,我发现这是一个解决方案。

try {
            
            

            String command = "C:\\AI\\Yolo_v4\\darknet\\build\\darknet\\x64\\darknet.exe detector test C:\\AI\\Yolo_v4\\darknet\\build\\darknet\\x64\\data\\obj.data C:\\AI\\Yolo_v4\\darknet\\build\\darknet\\x64\\cfg\\yolov4-obj.cfg C:\\AI\\Yolo_v4\\darknet\\build\\darknet\\x64\\backup\\rgbmodel\\yolov4-obj_last.weights -dont_show -ext_output C:\\Users\\felix\\Desktop\\yoloTestSet\\RGBTest\\IMG_2392.jpg";
            Process proc = Runtime.getRuntime().exec(command, null,
                    new File("C:\\AI\\Yolo_v4\\darknet\\build\\darknet\\x64"));
            
            BufferedReader br = new BufferedReader(
                    new InputStreamReader(proc.getErrorStream()));
            
            BufferedReader stdInput = new BufferedReader(new 
                     InputStreamReader(proc.getInputStream()));
                String line;
                while ((line = br.readLine()) != null)
                    System.out.println(line);
                
                while ((line = stdInput.readLine()) != null)
                    System.out.println(line);

            proc.waitFor();
            

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

一些所需的输出在 ErrorStream 中。此外,您需要完整路径并对 YOLO 本身进行小幅更改,因为会引发内部错误。“cmd /c start”不是必需的。


推荐阅读