IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

API standards et tierces Java Discussion :

[Process] recuperer entree et sortie d'un programme externe


Sujet :

API standards et tierces Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2005
    Messages
    113
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 113
    Par défaut [Process] recuperer entree et sortie d'un programme externe
    bonjour,

    je fais appelle au JDK's keytool dans mon programme avec:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Process proc = Runtime.getRuntime().exec("keytool -etc...");
    Le probleme c'est que cet utilitaire demande de remplir des champs une fois lance.
    J'aimerai donc recuperer l'entree et la sortie de ce programme pour les integrer dans mon IHM. Comment faire ?

  2. #2
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,


    Tout est dans l'API de la classe Process...

    a++

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2005
    Messages
    113
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 113
    Par défaut
    Ok, donc si je comprend bien, la sortie de mon subProcess est reliee a ma sortie standard. mais je ne sais pas comment reliee cette sortie a un JTexteArea par exemple.
    De plus, ca n'as pas l'air de marcher car lorsque je lance le subprocess je ne vois rien sur ma sortie standard.

  4. #4
    Membre Expert
    Homme Profil pro
    Dév. Java & C#
    Inscrit en
    Octobre 2002
    Messages
    1 414
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Dév. Java & C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2002
    Messages : 1 414
    Par défaut
    Le plus simple est que tu nous montres ton code.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2005
    Messages
    113
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 113
    Par défaut
    Ben en fait, je fais juste ca :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    try {
       proc = Runtime.getRuntime().exec("C:\\j2sdk1.4.2_07\\bin\\keytool -genkey -alias alias -keyalg RSA -keypass password -keystore ./config/SampleKeystore");
       proc.waitFor();			
       proc.destroy();
    } catch (IOException e1) {
       printError("secure error", e1 );
       throw new Exception();
    } catch (InterruptedException e) {
       printError("secure error", e );
       throw new Exception();
    }
    Deja, si je pouvais recuperer la sortie du programme quelque part ca serait deja pas mal. Pour ecrire, je verrai plus tard.

  6. #6
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par adiGuba
    Tout est dans l'API de la classe Process...
    As-tu regardé dans l'API ? La classe Process possèdent des méthodes pour accéder aux différents flux du processus : getInputStream(), getOutputStream() et getErrorStream().

    a++

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2005
    Messages
    113
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 113
    Par défaut
    Oui, merci j'ai bien vu ces trois methodes. Mais je ne comprend pas comment les utiliser.
    Une fois que j'ai recupere mon inputStream et mon outputStream, je les branche ou ?

  8. #8
    Expert confirmé
    Avatar de le y@m's
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2005
    Messages
    2 636
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Février 2005
    Messages : 2 636
    Par défaut
    regarde tu coté des classes :
    InputStreamReader
    OutputStreamWriter
    BufferedReader
    BufferedWriter
    PrintWriter
    (le package java.io en somme)
    Je ne répondrai à aucune question technique par MP.

    Pensez aux Tutoriels et aux FAQs avant de poster ;) (pour le java il y a aussi JavaSearch), n'oubliez pas non plus la fonction Rechercher.
    Enfin, quand une solution a été trouvée à votre problème
    pensez au tag :resolu:

    Cours Dvp : http://ydisanto.developpez.com
    Blog : http://yann-disanto.blogspot.com/
    Page perso : http://yann-disanto.fr

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2005
    Messages
    113
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 113
    Par défaut
    Bon alors je fais ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    Process proc = null;
    try {
    	proc = Runtime.getRuntime().exec("C:\\j2sdk1.4.2_07\\bin\\keytool -genkey -alias alias -keyalg RSA -keypass password -keystore ./config/SampleKeystore");
    	BufferedInputStream in = new BufferedInputStream(proc.getInputStream());
    	BufferedOutputStream out = new BufferedOutputStream(proc.getOutputStream());
    	BufferedReader reader = new BufferedReader(new InputStreamReader(in));
    	BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out));
     
    	System.out.println(reader.readLine());
     
    	proc.waitFor();			
    	proc.destroy();
    } catch (IOException e1) {
    	printError("secure error", e1 );
    	throw new Exception();
    } catch (InterruptedException e) {
    	printError("secure error", e );
    	throw new Exception();
    }

    Mais le programme se bloc sur mon readLine() car je suppose qu'il ne trouve rien a lire. A mon avis, je m'emmelle les pedales avec les entrees qui passent sorties et vice-versa...

  10. #10
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2005
    Messages
    113
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 113
    Par défaut
    Quelques infos complementaires...

    En fouillant un peu sur le forum, j'ai trouve un post de quelqu'un qui avait le probleme suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Runtime envt = Runtime.getRuntime(); 
    p = envt.exec("....fichier sql..."); 
    p.getOutputStream().close(); 
    p.waitFor(); 
    p.getInputStream().close(); 
    p.getErrorStream().close();
    Lorsqu'il faisait ca, son programme ne se terminait jamais. Si j'ai bien compris, c'est parceque le waitFor() attendait la fin des entrees donc il s'en sortait pas.

    J'ai donc essaye de faire ceci (juste pour voir) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Process proc = Runtime.getRuntime().exec("keytool -genkey -alias merge -keyalg RSA -keypass password -keystore " + sampleKeystore);
     
    proc.getInputStream().close();
    proc.getOutputStream().close();
    proc.getErrorStream().close();
     
    proc.waitFor();
    Et effectivement, mon process ne se bloc plus dans le waitFor(). Mais vu que je ferme les flux, je vois mal comment il pourrait afficher quelque chose.

    Le probleme c'est que je ne comprend pas bien comment fonctionne ces flux. Parceque ils m'empechent de ternminer convenablement mon process et je n'arrive pas a les lire. Alors qu'est ce que je dois en faire exactement ?

  11. #11
    Membre Expert
    Homme Profil pro
    Dév. Java & C#
    Inscrit en
    Octobre 2002
    Messages
    1 414
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Dév. Java & C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2002
    Messages : 1 414
    Par défaut
    Il faut savoir qu'un subProcess doit être vu comme un thread. Donc il "tourne" presque indépendamment du thread qu'il a créé (créateur). Je dis presque car le subProcess est relié à son créateur par ses canaux standards d'entrée, de sortie et d'erreur. Ces canaux sont des tampons.

    Le subProcess peut être bloqué en lisant son entrée (tampon vide) ou en écrivant dans les canaux de sortie (tampon plein). Ces tampons ont apparemment une petite taille.

    On remarque qu'il est nécessaire que l'on fournisse des données au canal d'entrée et qu'on lit les canaux de sortie indépendamment l'une de l'autre. Pour arriver à ce but nous allons utiliser l'interface Thread.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
         /* Il es préférable d'utiliser cette méthode pour passer les arguments.
             Le premier argument est le fichier à exécuter */
         String[] arguments = {"("C:\\j2sdk1.4.2_07\\bin\\keytool ", "-genkey ", "-alias alias ", "-keyalg RSA", "-keypass password", "-keystore ./config/SampleKeystore"};
         Process proc = Runtime.getRutime().exec(arguments);
    Nous allons créer un thread qui lit la sortie standard des erreur du subProcess et l'écrit dans celle du créateur.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
        new Thread() {
            public void run() {
                try {
                    BufferedInputStream errStream = 
                        new BufferedInputStream(proc.getErrorStream());
                    byte[] buffer = new byte[128];
                    int read;
     
                    while ((read = errStream.read(buffer, 0, buffer.length)) != -1) {
                        System.err.write(buffer, 0, read);
                    }
                    errStream.close();
                   }
                   catch (IOException ioe) {
                      ioe.printStackTrace();
                }
            }
        }.start();
    Le même principe pour la sortie standard
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
        new Thread() {
            public void run() {
                try {
                    BufferedInputStream outStream = 
                        new BufferedInputStream(proc.getInputStream());
                    byte[] buffer = new byte[128];
                    int read;
     
                    while ((read = outStream.read(buffer, 0, buffer.length)) != -1) {
                        System.out.write(buffer, 0, read);
                    }
                    outStream.close();
                }
                catch (IOException ioe) {
                    ioe.printStackTrace();
                }
            }
        }.start();
    De nouveau le même principe pour l'entrée. Il est nécessaire de lui fournir toutes le données sinon le suProcess va bloquer sur son entrée standard. C'est pour cette raison qu'il est préférable si possible de lui fournir les données via les arguments.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
        FileInputStream inpFile = new FileInputStream(new File("C:\\myData.txt"));
        final BufferedInputStream input = new BufferedInputStream(inpFile);
        new Thread() {
            public void run() {
                try {
                    BufferedOutputStream inpStream = 
                        new BufferedOutputStream(proc.getOutputStream());
                    byte[] buffer = new byte[256];
                    int read;
     
                    while ((read = input.read(buffer, 0, buffer.length)) != -1) {
                        inpStream.write(buffer, 0, read);
                    }
                } catch (IOException ioe) {
                    ioe.printStackTrace();
                }
            }
        }.start();
     
        /* N'oublie pas de fermer input et inFile à la fin */
    On attend que le subProcess termine et nous retourne son status code.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
        int status = proc.waitFor();
    L'appel à waitFor est bloquant alors je te conseille cette deuxième forme.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
        Thread waitFor = new Thread() {
            public void run() {
                try {
                    proc.waitFor();
                }
                catch(InterruptedException ie) {
                    ie.printStackTrace();
                }
            }
        };
        waitFor.start();
     
        /* On attend jusqu'à 60 secondes que le subProcess se termine */
        int status = -1;
        try {
            waitFor.join(60000);
            status = process.exitValue();
        }
        catch (InterruptedException ie) {
            ie.printStackTrace();
        }
     
     
        input.close();
        inpFile.close();
    Avant d'intégrer ce code dans ta IHM, je te conseille de le tester dans un sous-projet.

    A toi d'améliorer certaines parties du code, principalement le traitement des exceptions.

    Bon courage

  12. #12
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2005
    Messages
    113
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 113
    Par défaut
    Wouha !

    Merci beaucoup. C'est bien plus clair comme ca.
    J'ai finalement pu eviter d'avoir a utiliser les entrees/sorties dans mon programme. Je n'ai pas le temps de tester ce code mais je pense que ca devrait marcher. Je le met dans un coin pour une prochaine fois.

    Merci encore.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 3
    Dernier message: 25/11/2014, 11h57
  2. récupérer la sortie d'un programme externe
    Par diodio13fr dans le forum Débuter avec Java
    Réponses: 2
    Dernier message: 23/11/2009, 23h15
  3. recuperer sortie d'un programme console
    Par jmjmjm dans le forum C++
    Réponses: 10
    Dernier message: 27/02/2008, 15h21
  4. Récupérer sortie d'un programme externe
    Par EricPellegrini dans le forum Général Python
    Réponses: 7
    Dernier message: 16/05/2007, 20h11
  5. Programmer une entree ou sortie en C++
    Par stpaul04 dans le forum C++
    Réponses: 1
    Dernier message: 20/11/2006, 19h09

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo