首页 > 解决方案 > Java Process Builder - 无法运行简单的程序

问题描述

我有一个名为darknet. 这是一个由Darknet制成的 C 程序。

我想在如下所示darknet的文件夹Darknet中运行程序:

在此处输入图像描述

我将darknet使用 Java Process Builder 运行,但是当我运行此代码时,我没有得到任何响应:

    // Arguments
    String darknetNamePath = darknet.getValue().getFilePath().replace("Darknet/", "./");
    String configurationFlag = configuration.getValue().getFilePath().replace("Darknet/", "");
    String weightsFlag = weights.getValue().getFilePath().replace("Darknet/", "");
    String imageFlag = "data/cameraSnap.png";
    String thresholdFlag = "-thresh " + thresholds.getValue();
    
    // Process builder
    ProcessBuilder processBuilder = new ProcessBuilder();
    processBuilder.directory(new File("Darknet")); // We need to stand inside the folder "Darknet"
    String commandString = "detect " + configurationFlag + " " + weightsFlag + " " + imageFlag + " " + thresholdFlag;
    System.out.println("darknetNamePath  = " + darknetNamePath);
    System.out.println("commandString  = " + commandString);
    processBuilder.command(darknetNamePath, commandString);
    Process process = processBuilder.start();
    BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
    String line;
    while ((line = reader.readLine()) != null) {
        System.out.println(line);
    }
    int exitCode = process.waitFor();
    System.out.println("\nExited with error code : " + exitCode);

这是我的输出。为什么它对我不起作用?

darknetNamePath  = ./darknet
commandString  = detect cfg/yolov2-tiny.cfg weights/yolov2-tiny.weights data/cameraSnap.png -thresh 0.8

Exited with error code : 0

darknet但是当我通过终端调用文件时,它就可以工作了。

./darknet detect cfg/yolov2-tiny.cfg weights/yolov2-tiny.weights data/cameraSnap.png -thresh 0.6

更新 2:

这是我的更新。

    // Arguments
    String darknetNamePath = darknet.getValue().getFile().getAbsolutePath();
    String configurationFlag = configuration.getValue().getFilePath().replace("Darknet/", "");
    String weightsFlag = weights.getValue().getFilePath().replace("Darknet/", "");
    String imageFlag = "data/cameraSnap.png";
    String thresholdFlag = "-thresh " + thresholds.getValue();

    // Process builder
    ProcessBuilder processBuilder = new ProcessBuilder();
    processBuilder.command(darknetNamePath, "detect", configurationFlag, weightsFlag, imageFlag, thresholdFlag);
    Process process = processBuilder.start();
    if (process.getInputStream().read() == -1) {
        System.out.println(darknetNamePath);
        System.out.println("detect");
        System.out.println(configurationFlag);
        System.out.println(weightsFlag);
        System.out.println(imageFlag);
        System.out.println(thresholdFlag);
        System.out.printf("ERROR!");
    }
    BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
    String line;
    while ((line = reader.readLine()) != null) {
        System.out.println(line);
    }
    int exitCode = process.waitFor();
    System.out.println("\nExited with error code : " + exitCode);

输出:

/home/dell/Dokument/GitHub/Vaadin-DL4J-YOLO-Camera-Mail-Reporter/Vaadin-DL4J-YOLO-Camera-Mail-Reporter/Darknet/darknet
detect
cfg/yolov2-tiny.cfg
weights/yolov2-tiny.weights
data/cameraSnap.png
-thresh 0.3
ERROR!
Exited with error code : 0

更新 3:

这有效:

            // Arguments
            String darkPath = darknet.getValue().getFilePath().replace("Darknet/", "./"); // We need to call ./darknet, not absolute path
            String configurationFlag = configuration.getValue().getFilePath().replace("Darknet/", "");
            String weightsFlag = weights.getValue().getFilePath().replace("Darknet/", "");
            String imageFlag = "data/camera.png";
            String thresValue = String.valueOf(thresholds.getValue());

            // Process builder
            ProcessBuilder processBuilder = new ProcessBuilder();
            processBuilder.directory(new File("Darknet")); // Important
            processBuilder.command(darkPath, "detect", configurationFlag, weightsFlag, imageFlag, "-thresh", thresValue);
            processBuilder.redirectErrorStream(true); // Important
            Process process = processBuilder.start();
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
            int exitCode = process.waitFor();
            System.out.println("\nExited with error code : " + exitCode);

标签: javaprocessbuilderdarknet

解决方案


您的命令必须将所有参数分成单独的部分 - 包括thresholdFlag. 检查可执行文件是否存在是个好主意。如果不是,您应该检查它的位置或修复您的 Path 变量以确保它可以被定位:

File darkpath = new File(darknetNamePath);
String [] cmd = new String[] { darkpath.getAbsolutePath(), "detect", configurationFlag, weightsFlag, imageFlag, "-thresh", String.valueOf(thresholds.getValue()) };

System.out.println("Path: "+darkpath+ " exists="+darkpath.exists());
System.out.println("exec "+Arrays.toString(cmd));

processBuilder.command(cmd);

也值得处理 STDERR,最简单的方法是在调用之前重定向 STDERR=>STDOUTprocessBuilder.start()

processBuilder.redirectErrorStream(true);

如果您希望 Java 在不添加绝对路径前缀的情况下启动可执行文件,则它需要位于以下目录之一中:

System.out.println("PATH COMPONENTS FOR JAVA LAUNCH:");
Arrays.asList(System.getenv("PATH").split(File.pathSeparator)).forEach(System.out::println);

推荐阅读