当前位置: 首页 > 知识库问答 >
问题:

ProcessBuilder中的进程未将输出定向到字符串

井洲
2023-03-14

我正在创建一个使用服务代理运行多个模块的流程。这些模块将在流程结束时返回一个字符串,初始服务代理调用将返回并打印该字符串。但是,我来自流程构建器的进程没有返回我的字符串。我放置了print语句来告诉我不同模块何时运行,它打印正确的答案,但不会将其作为字符串返回给服务代理。

服务经纪人

import java.io.*;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Scanner;
import java.util.stream.Collectors;

public class ServiceBrokerTest {
    public static String main(String[] args) throws FileNotFoundException {
        String serviceName = args[0];
        String parmList = args[1];
        try {
            Path filePath = Paths.get("Service.txt");
            String absPath = filePath.toFile().getAbsolutePath();
            File serviceText = new File(absPath);

            Scanner scan = new Scanner(serviceText);
            String[] currentLine = null;
            while (scan.hasNextLine()){
                currentLine = scan.nextLine().split(",");

                if (currentLine[0].equals(serviceName)){
                    ProcessBuilder processCompile = new ProcessBuilder();
                    processCompile.directory(new File(System.getProperty("user.dir")));
                    String[] parmsProcessCompile = {"javac", currentLine[1]};
                    processCompile.command(parmsProcessCompile);

                    Process c = processCompile.inheritIO().start();
                    c.waitFor();
                    c.destroy();

                    ProcessBuilder processRun = new ProcessBuilder();
                    processRun.directory(new File(System.getProperty("user.dir")));
                    String runName = currentLine[1].split("\\.")[0];
                    String[] parmsProcessRun = {"java", runName,parmList};
                    processRun.command(parmsProcessRun);
                    Process r = processRun.inheritIO().start();
                    r.waitFor();
                    BufferedReader stdOut = new BufferedReader(new InputStreamReader(r.getInputStream()));
                    String stdOutStr = stdOut.lines().collect(Collectors.joining(System.lineSeparator()));

                    return stdOutStr;
                }
            }
        }
        catch (Exception e){
            String[] temp = new String[]{"English", "703"};
            System.out.println(Error.error(temp));
        }

        return null;
    }


}

翻译

    public class Translate {
    public static void main(String[] args) throws IOException {
        translate(args);
    }
    /**
     *
     * @param args  string array. first index will be the filename, second will be the english word to translate from
     * @return  call to service broker with instructions for error call or text broker call
     */
    public static String translate(String[] args) throws IOException {

        ServiceBrokerTest serviceBroker = new ServiceBrokerTest();

        try {
            String[] argArray = args[0].split(",");
            String filename = argArray[0];
            String englishWord = argArray[1];
            String searchMethod = argArray[2];

            // check if the file exists, if not, call error module
            if (!searchFile(filename)) {
                // call error module and return
                return ServiceBrokerTest.main(new String[] {"Error", "English" + ", 805"});

            }
            //for testing
            System.out.println("process run Trans");
            //-------------------------
            return ServiceBrokerTest.main(new String[]{"TB", filename + "," + englishWord + "," + searchMethod});
        } catch (Exception e) {
            return ServiceBrokerTest.main(new String[] {"Error", "English" + ", 404"});
        }
    }

    /**
     *
     * @param filename  name of file you are searching for
     * @return true if file exists, false if otherwise
     */
    public static boolean searchFile(String filename) {
        File temp = new File(filename);
        return temp.isFile();
    }

}

文本代理

public class TextBroker {

    public static void main(String[] args) throws FileNotFoundException {
        TB(args);
    }

    /**
     * Creates the file from the fileName that was passed down from the service broker
     */
    public static File fileCreation(String filename) throws FileNotFoundException {
        File input = new File(filename);
        return input;
    }


    /**------------------------------------------------------------------------------------------------
     * Search Method
     * ------------------------------------------------------------------------------------------------
     * Takes the passed parameters parm and searchMethod as well as the file created by fileCreation
     * and parses through the given file in search for the correct or corresponding output.
     * ------------------------------------------------------------------------------------------------
     */
    public static String fileSearch(File file, String parm, String searchMethod) throws FileNotFoundException {
        Scanner fileScan = new Scanner(file);
        String[] currentLine;

        /**
         * If there is a comparison that needs >= or <= then the value has to be converted from a
         * string to an int in order for proper comparison of the values.
         */
        int convertedString = 0;

        /**------------------------------------------------------------------------------------------------
         * Search Blocks
         * ------------------------------------------------------------------------------------------------
         * Each if block works by converting the passed parm if necessary, like for >= or <=,
         * then using a while loop it searches the file, splitting the current line and comparing the
         * first value of the line. If it follows the searchMethod parm then it is correct and is returned
         * by the method as a string.
         * ------------------------------------------------------------------------------------------------
         */
        if (searchMethod.equals("<=")){
            convertedString = Integer.parseInt(parm);
            while (fileScan.hasNextLine()){
                currentLine = fileScan.nextLine().split(",");

                if (convertedString <= Integer.parseInt(currentLine[0]) ){
                    System.out.println(currentLine[1]);
                    return currentLine[1];
                }
            }
        }
        else if (searchMethod.equals(">=")){
            convertedString = Integer.parseInt(parm);
            while (fileScan.hasNextLine()){
                currentLine = fileScan.nextLine().split(",");

                if (convertedString <= Integer.parseInt(currentLine[0]) ){
                    System.out.println(currentLine[1]);
                    return currentLine[1];
                }
            }
        }
        else if (searchMethod.equals("=")){
            while (fileScan.hasNextLine()){
                currentLine = fileScan.nextLine().split(",");

                if (currentLine[0].equals(parm)){
                    System.out.println(currentLine[1]);
                    return currentLine[1];
                }
            }
        }

        return null;
    }

    /**
     * The parameters are recieved via an array of strings as args which are assigned variables
     * and passed to the required methods fileCreation and fileSearch.
     * This is in a try catch block so that a fileNotFound is caught and triggers an error call
     * or any other error is caught.
     */
    public static String TB(String[] args) throws FileNotFoundException {
        System.out.println("Process run TB");
        try {
            String[] splitArgs = args[0].split(",");
            String fileName = splitArgs[0];
            String parm = splitArgs[1];
            String searchMethod = splitArgs[2];
            String returnString = fileSearch(fileCreation(fileName),parm, searchMethod);
            return returnString;
        } catch (Exception e) {
            ServiceBrokerTest serviceBroker = new ServiceBrokerTest();
            return serviceBroker.main(new String[] {"Error", "English" + ", 404"});
        }

    }
}

SB被赋予参数{"Trans,"german.txt, dog,="},它将[1]字符串传递给翻译模块,因此trans,它沿着parms传递给返回正确翻译单词的TextBroker。我基本上需要将这个单词从TextBroker返回到初始服务代理调用和打印。我无法从Text Broker打印它,我们需要它向下传递。我已经尝试了一整条示例线程,即使我的print语句表明子进程正在达到返回字符串的正确点,也无法让我的SB返回除null之外的任何内容。也许我错过了一些简单的东西,但我看不到哪里出了问题。如果您需要,我可以提供更多文件以供运行,请告诉我。

谢谢你的帮助。

共有1个答案

冯卓
2023-03-14

您在process builder代码中犯了多个错误;你需要在这起作用之前把它们都修好。

inHeritage IO()字面意思是:忘记. getInputStream()重定向以及所有这些爵士乐,只继承java进程本身的标准in/out/err。你特别不想要的,所以摆脱它。

但这还不够。

然后,您首先调用. waitFor(),然后打开输入流。这不起作用——一旦进程死亡,就没有输入流可供您获取。

您需要开始该过程,然后读取数据,然后如果必须,您可以等待。

下面是我的一个项目中的一些示例代码:

private static <E extends Throwable> String exec0(String description, Function<String, E> exceptionFactory, String... args) throws E {

    Process process; try {
        process = new ProcessBuilder(args).redirectErrorStream(true).start();
    } catch (IOException e) {
        throw rethrow(e, "Cannot execute " + description, exceptionFactory);
    }
    
    String output; try {
        @Cleanup var in = process.getInputStream();
        output = new String(in.readAllBytes(), StandardCharsets.US_ASCII);
    } catch (IOException e) {
        throw rethrow(e, "Cannot stream results of " + description, exceptionFactory);
    }
    
    int v; try {
        v = process.waitFor();
    } catch (InterruptedException e) {
        throw rethrow(e, "Executing " + description + " interrupted", exceptionFactory);
    }
    
    if (v != 0) throw exceptionFactory.apply(description + " returned with error code " + v + ": " + output);
    return output;
}

private static <E extends Throwable> E rethrow(Throwable source, String prefix, Function<String, E> exceptionFactory) {

    String msg = source.getMessage() == null ? prefix : (prefix + ": " + source.getMessage());
    E ex = exceptionFactory.apply(msg);
    if (source.getCause() != null) ex.initCause(source.getCause());
    ex.setStackTrace(source.getStackTrace());
    return ex;
}

它做了一些花哨的工作,让您自动为您的API设计抛出适当的异常(通常,“我在主机操作系统上运行应用程序”应该是一个实现细节,因此ProcessBuilder抛出的特定异常不适合只是盲目地传递;它们需要根据您的API进行重申。

如果你不在乎它,你可以轻易地把它撕下来。

关键部分是首先打开输入流(直到之后才调用waitFor),然后读取所有字节<代码>输入。readAllBytes()是一种非常方便的方法

注意:@Cleanup是lombok Cleanup。如果不使用它,那么使用try(var in=x.getInputStream()){…} -你需要安全关闭那东西。

 类似资料:
  • 问题内容: 我正在尝试使用以下代码重定向在ProcessBuilder的帮助下启动的流程的输出 但是它以失败告终 线程“主”中的异常java.io.IOException:无法运行程序“ / myScript >> / myLogFile 2>&1 <&-&”:java.io.IOException:error = 2,java.lang中没有此类文件或目录.ProcessBuilder.star

  • 问题内容: 我想从Groovy程序中执行foo.bat,并将生成的进程的输出重定向到stdout。Java或Groovy代码示例都可以。 foo.bat可能需要花费几分钟才能运行并生成大量输出,因此我希望在生成后立即查看输出,而不是必须等到该过程完成之后才能立即查看所有输出。 问题答案: 它使用一个类读取执行的程序生成的所有输出,并将其显示在其自己的stdout中。

  • 问题内容: 我有一个函数的返回类型为VOID,它直接在控制台上打印。 但是,我需要字符串形式的输出,以便可以对其进行处理。 由于我无法使用返回类型为VOID的函数进行任何更改,因此我不得不将该输出重定向到字符串。 如何在JAVA中重定向它? 关于将stdout重定向到字符串有很多问题,但是它们仅重定向从用户获取的输入,而不重定向某些函数的输出… 问题答案: 如果功能正在打印到,则可以使用更改为你提

  • 问题内容: 我正在使用以下代码启动流程构建器。我想知道如何将其输出重定向到字符串。 我尝试使用,但似乎没有用。 问题答案: 从阅读。您可以将输出附加到:

  • 在我看来,到目前为止,JFrame中发生的一切都留在JFrame中。(可能应该进入JavaFX而不是Swing) 假设您有一个 JFrame 类 (gui_frame),它利用 JButtons 和一个名为 HandlerClass 的嵌套类来实现 ActionListener,如下所示: 然后你有主代码,它调用这个gui_frame类。 本质上,我试图在运行时将被单击后的按钮名称存储在JFram

  • 问题内容: TextPanel.java FormPanel.java JumpHosts.java 因此,每当我单击任何按钮时,输出都将被重定向到仅一个文本区域,而其他似乎无法使用。即到最后创建的标签。我希望当我单击按钮1时,它应该写入选项卡1,而当我单击按钮2时,它应该写入选项卡2,依此类推。 我不熟悉Java的例子 问题答案: 在JumpHosts中: 您创建一个实例,该实例在程序中没有其他