Visualizzazione dei risultati da 1 a 5 su 5
  1. #1

    [Java] Capire la classe Process

    ho dato un'occhiata a un libro che ho casa che spiega a grandi linee Process e come eseguire comandi di sistema.
    ho creato questo:
    codice:
    public class ls {
    
        public static void main(String[] args) throws IOException {
            String cmd = "ls -la /media/MATTE";
            Process proc = Runtime.getRuntime().exec(cmd);
            InputStream input = proc.getInputStream();
            InputStreamReader reader = new InputStreamReader(input);
            BufferedReader br = new BufferedReader(reader);
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
            input.close();
        }
    }
    funziona ma nn ho ben chiare alcune cose.
    InputStream, InputStreamReader e BufferedReader sono essenziali o ci sono anche altri modi per per stampare i risultati dei comandi?
    se io volessi in questo main eseguire due comandi (ad esempio rm per eliminare un file e poi ls) devo creare un InputStream, un InputStreamReader e un BufferedReader per ogni comando??

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284

    Re: [Java] Capire la classe Process

    Originariamente inviato da fermat
    InputStream, InputStreamReader e BufferedReader sono essenziali o ci sono anche altri modi per per stampare i risultati dei comandi?
    Il punto principale è che se si avvia un processo esterno con gli exec() di Runtime (o con ProcessBuilder da Java 5) gli "stream" in/out/err del processo sono comunque rediretti in automatico da/verso la applicazione Java. Anche se la tua applicazione Java l'hai lanciata da una "console", gli stream del processo lanciato in ogni caso non operano su quella console.

    In sostanza quindi gli stream in/out/err li devi gestire da Java. E questo vuol dire che se il processo si aspetta qualcosa su standard-input, allora da Java devi scrivere tu qualcosa sul OutputStream (getOutputStream di Process) e se il processo scrive qualcosa su standard-output/error lo devi leggere dagli InputStream (getInputStream/getErrorStream di Process).

    E nota: se il processo fa molto output, lo devi leggere. Per questioni di buffering, se non lo leggi il processo lanciato si può addirittura bloccare.

    Per tornare alla questione delle classi, quindi devi leggere. Con quali classi ... dipende. Dipende cioè da cosa scrive il processo e da cosa devi farci.
    Se l'obiettivo è solo quello ad esempio di leggere l'output del processo "a righe", allora è appropriato usare InputStreamReader + BufferedReader perché appunto quest'ultimo ti permette di leggere "a righe".

    Se invece dovessi ad esempio leggere pari pari i byte dallo standard-output del processo e "buttarli" sempre per esempio su un file o un socket, allora basta leggere "a blocchi" di byte dal InputStream del Process.

    Originariamente inviato da fermat
    se io volessi in questo main eseguire due comandi (ad esempio rm per eliminare un file e poi ls) devo creare un InputStream, un InputStreamReader e un BufferedReader per ogni comando??
    Non necessariamente. Se "rm" non fa ouput potresti anche non leggerlo.
    Il punto è che se devi fare questa gestione più volte e magari in certi casi "buttare" via l'ouput o ad esempio dover leggere sia lo standard "output" che il "error" contemporaneamente, allora devi cercare di incapsulare la gestione in un metodo o magari in una apposita classe. Magari (nel caso dei due contemporaneamente) con l'aiuto di più thread.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    grazie per la risposta dettagliata!

    ero arrivato ad alcune conclusioni ma nn così precise.
    facendo questo tentativo mi sono infatti accorto che i vari stream e buffer mi servono solo per mostrare l'output di ls (in questo caso).
    infatti:
    codice:
        public static void main(String[] args) throws IOException {
            String cmd = "mkdir /home/matte/Desktop/a";
            String cmdls = "ls -l /home/matte/Desktop";
            Process procChmod = Runtime.getRuntime().exec(cmd);
            Process proc = Runtime.getRuntime().exec(cmdls);
            InputStream input = proc.getInputStream();
            InputStreamReader reader = new InputStreamReader(input);
            BufferedReader br = new BufferedReader(reader);
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
            input.close();
        }
    questo funziona.
    il programmino che ho in mente avrà un solo output, il risultato dei permessi impostati o in caso l'errore se nn si hanno permessi sufficienti.

    ho visto però che c'è anche ProcessBuilder ma nn ho ben capito la differenza.
    quando usare Process o PB??

  4. #4
    Ciao,
    Io avrei un altro dubbio. Sto usando Process per avviare Iperf che serve a testare il traffico in una rete.
    Il mio problema è che ottengo l'output solo alla fine e non durante l'esecuzione del processo.
    E' possibile farlo??
    Scrivo il mio codice nel caso non mi fossi spiegato bene:

    Runtime r= Runtime.getRuntime();
    try{
    Runtime rt = Runtime.getRuntime();
    Process proc = rt.exec(" src\\iperf3\\iperf3.exe -c 127.0.0.1 -p 5201");
    InputStream stdin = proc.getInputStream();
    InputStreamReader isr = new InputStreamReader(stdin);
    BufferedReader br = new BufferedReader(isr);
    while ( (line = br.readLine()) != null)
    System.out.println(line);
    PrintStream sbbb = null;
    sbbb.append(line);
    System.out.println(sbbb);
    }catch(Exception e){
    System.out.println("Errore");
    }

  5. #5
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da Vincenzo89 Visualizza il messaggio
    Sto usando Process per avviare Iperf che serve a testare il traffico in una rete.
    Il mio problema è che ottengo l'output solo alla fine e non durante l'esecuzione del processo.
    In generale, dipende solo da cosa fa il processo lanciato. Se da Java fai già il loop continuo sempre in attesa di righe, questo è già il massimo che puoi fare. Non può "tirar" fuori nulla di più o forzare alcunché.

    Iperf potrebbe non fare dei flush subito o potrebbe dover essere istruito (con delle opzioni) per inviare output utile durante il suo lavoro e non solo alla fine. Non lo conosco ... non so cosa fa né che output produce.

    Non mi è chiaro il senso della parte finale del tuo codice. Questo (e solo questo!) è il ciclo:

    codice:
    while ( (line = br.readLine()) != null)
        System.out.println(line);

    ed è ok. Ma poi

    codice:
    PrintStream sbbb = null;
    sbbb.append(line);
    System.out.println(sbbb);

    questo non ha granché senso. Se sbbb è null non puoi invocarci append! E se anche potessi, quel line è solo l'ultima riga letta.
    E poi fare un print di un oggetto PrintStream non ha nemmeno senso (se non per debugging).


    P.S. non portare a galla discussioni di 5 anni fa.
    Ultima modifica di andbin; 22-08-2015 a 09:24
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.