Як перанакіраваць выснову Process Будаўніка ў радок?

Я выкарыстоўваю наступны код, каб пачаць працэс builder.I хоча ведаць, як я магу перанакіраваць выснову ў радок.

ProcessBuilder pb = new ProcessBuilder(System.getProperty("user.dir")+"/src/generate_list.sh", filename);
Process p = pb.start();

Я паспрабаваў з дапамогай ByteArrayOutputStream , але гэта не падобна на працу.

39
«Гэта не падобна на працу» не з'яўляецца апісаннем праблемы. <�Код> ProcessBuilder не мае патокаў, але Працэс робіць. Вы не пачынаеце ProcessBuilder , вы выкарыстоўваеце яго стварыць а Process , а затым, пачынаючы <�я> што. будзьце дакладныя.
дададзена аўтар EJP, крыніца
як вы выкарыстоўвалі ByteArrayOutputStream ?
дададзена аўтар fGo, крыніца

8 адказы

Чытанне з InputStream . Вы можаце дадаць выснова ў StringBuilder :

BufferedReader reader = 
                new BufferedReader(new InputStreamReader(process.getInputStream()));
StringBuilder builder = new StringBuilder();
String line = null;
while ( (line = reader.readLine()) != null) {
   builder.append(line);
   builder.append(System.getProperty("line.separator"));
}
String result = builder.toString();
47
дададзена
@Fabian Гэта лёгка можна зрабіць з дапамогай processBuilder.inheritIO()
дададзена аўтар Reimeus, крыніца
Вы чакаеце, што я адкажу, што, не бачачы код? Пачаць новае пытанне уключаючы Minimal, поўны і правяраемы прыклад і поўнае апісанне праблемы ў Вас з
дададзена аўтар Reimeus, крыніца
@Reimeus адкідаецца арыгінальны канец-радкі сімвал (ы) і замяняе, што на бягучай платформе, якая можа адрознівацца.
дададзена аўтар neuralmer, крыніца
Звярніце ўвагу, што калі вы не перанакіраваць паток памылак, вам трэба будзе захапіць выхады з патоку памылак, а таксама уваходнага патоку, у адваротным выпадку працэс будзе вісець. Вы павінны сабраць патокі ў асобных патоках, у адваротным выпадку ваш асноўны паток будзе вісець. У гэтым выпадку пошук «індык нітка» для поўнага рашэння.
дададзена аўтар Richard Whitehead, крыніца
Вы можаце дадаць, як атрымаць паток памылак, ці абодвух.
дададзена аўтар Fabian, крыніца
@Reimeus нават калі я атрымліваю вынік карэкцыі мая лінія роўная нуля, чаму?
дададзена аўтар MertG, крыніца
17
дададзена
Паток ўсё яшчэ павінен быць зачынены пасля гэтага, ці не так?
дададзена аўтар jbird, крыніца
Не ўпэўнены. Я не бачыў ніякіх ProcessBuilder прыкладаў, якія закрываюць InputStream. Адказ аб працэсе кажа, што вы ўсё роўна павінны зачыніць струмень .... stackoverflow.com/questions/7097697/…
дададзена аўтар Daniel, крыніца

Вы маглі б зрабіць нешта накшталт гэтага:

private static BufferedReader getOutput(Process p) {
    return new BufferedReader(new InputStreamReader(p.getInputStream()));
}

private static BufferedReader getError(Process p) {
    return new BufferedReader(new InputStreamReader(p.getErrorStream()));
}
...
Process p = Runtime.getRuntime().exec(commande);
BufferedReader output = getOutput(p);
BufferedReader error = getError(p);
String ligne = "";

while ((ligne = output.readLine()) != null) {
    System.out.println(ligne);
}

while ((ligne = error.readLine()) != null) {
 System.out.println(ligne);
}
9
дададзена
Гэта можа прывесці да завісання ў тым выпадку, працэс запісвае большую колькасць дадзеных у стандартны струмень памылак - гл stackoverflow.com/questions/16983372/…
дададзена аўтар L.R., крыніца

Для Java 7 і 8 гэта павінна працаваць:

private String getInputAsString(InputStream is)
{
   try(java.util.Scanner s = new java.util.Scanner(is)) 
   { 
       return s.useDelimiter("\\A").hasNext() ? s.next() : ""; 
   }
}

Затым у кодзе, зрабіце наступнае:

String stdOut = getInputAsString(p.getInputStream());
String stdErr = getInputAsString(p.getErrorStream());

I shamelessly stole that from: How to redirect Process Builder's output to a string?

3
дададзена

Java 8 Прыклад:

public static String runCommandForOutput(List params) {
    ProcessBuilder pb = new ProcessBuilder(params);
    Process p;
    String result = "";
    try {
        p = pb.start();
        final BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));

        StringJoiner sj = new StringJoiner(System.getProperty("line.separator"));
        reader.lines().iterator().forEachRemaining(sj::add);
        result = sj.toString();

        p.waitFor();
        p.destroy();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return result;
}

выкарыстанне:

List params = Arrays.asList("/bin/sh", "-c", "cat /proc/cpuinfo");
String result = runCommandForOutput(params);

Я выкарыстоўваю гэты дакладны код і ён працуе добра для аднаго або некалькіх вынікаў лініі. Вы можаце дадаць апрацоўшчык патоку памылак, а таксама.

3
дададзена

Пасля спробы апрацоўваць розныя выпадкі (апрацоўваць як патокі высновы і не блакіруе любы з іх, завяршыць працэс пасля тайм-аўту, належным чынам пазбегнуць слэш, двукоссі, адмысловыя знакі, прабелы, ....) Я здаўся і знайшоў <�моцны> Apache Commons Exec https://commons.apache.org/proper/commons -exec/tutorial.html , што, здаецца, робіць усе гэтыя рэчы даволі добра.

Я рэкамендую ўсім, каму трэба спасылацца на знешні працэс у Java, каб выкарыстоўваць бібліятэку Apache Commons Exec замест таго, каб вынаходзіць яго зноў.

2
дададзена
Вялікі дзякуй. Я спрабую выканаць праграму wkhtmltopdf з аргументамі, выкарыстоўваючы ProcessBuilder. Гэта было нармальна, у Windows, але на сэрвэры Linux гэта не атрымалася, і я не быў не ў стане атрымаць выхад з BufferedReader. Аднак усё было лёгка з ВікіСховішча Exec і яна працавала добра ў абедзвюх аперацыйных сістэмах.
дададзена аўтар jmoran, крыніца

Проста дадайце .inheritIO (); у працэсе будаўнік лініі.

IE:

<�Код> ProcessBuilder ПБ = новы ProcessBuilder (script.sh) .inheritIO ();

1
дададзена
@MarkoBonaci см прыняты адказ на гэтае пытанне. Вы павінны выкарыстоўваць BufferedReader чытач = новы BufferedReader (новы InputStreamReader (process.getInputStream ())); а затым пабудаваць StringBuilder з выхадам.
дададзена аўтар bogdan.rusu, крыніца
Варта адзначыць, што метад .inheritIO() для Java 7 і вышэй
дададзена аўтар bogdan.rusu, крыніца
Так як атрымаць радок высновы каманды?
дададзена аўтар Marko Bonaci, крыніца
Гэта перанакіроўвае працэс у STDOUT і Stderr на стандартны вывад і памылкі ў Java; яна не дазваляе захопліваць выснова ў выглядзе радка.
дададзена аўтар Andrew Rueckert, крыніца

У Java 8 ёсць добры лініі() паток, які вы можаце камбінаваць з string.join і System.lineSeparator ():

    try (BufferedReader outReader = new BufferedReader(new InputStreamReader(p.getInputStream()))
    {
        return String.join(System.lineSeparator(), outReader.lines().collect(toList()));
        \\ OR using jOOλ if you like reduced verbosity
        return Seq.seq(outReader.lines()).toString(System.lineSeparator())
    }
1
дададзена