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

Langage Java Discussion :

problème lecture stdout


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Août 2005
    Messages
    411
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2005
    Messages : 411
    Par défaut problème lecture stdout
    bonjour,

    Après avoir fait un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    process = Runtime.getRuntime().exec("cmd.exe /k"+" "+cmd);
    ceci fonctionne bien mais lire le buffer de sortie avec le code suivant ne fonctionne pas :

    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
    InputStream stdout = process.getInputStream();
    		InputStreamReader stdoutReader = new InputStreamReader (stdout);
    		BufferedReader stdoutBuffer = new BufferedReader (stdoutReader);
     
     
     
    		try {
    			// On récupère chaque ligne du STDOUT:
    			String line; 
    			while ( ( line = stdoutBuffer.readLine() ) != null ) {
    				reponse=reponse+line;
    			}
    		} catch (IOException e) {
     
    		}
     
    		return reponse;
    	}


    quelqu'un a une idée ?

    merci

  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,

    Citation Envoyé par youp_db
    le code suivant ne fonctionne pas
    C'est à dire ?????


    Citation Envoyé par youp_db
    quelqu'un a une idée ?
    Non... mais ton code n'est pas très "propre" :
    • Le flux stdout n'est pas fermé.
    • La concaténation de String avec l'opérateur + est vraiment très "lourd", il vaut mieux utiliser un StringBuffer/StringBuilder...
    • Ton catch est vide !!!
    a++

    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
    InputStream stdout = process.getInputStream();
            InputStreamReader stdoutReader = new InputStreamReader (stdout);
            BufferedReader stdoutBuffer = new BufferedReader (stdoutReader);
     
     
     
            try {
                // On récupère chaque ligne du STDOUT:
                String line; 
                while ( ( line = stdoutBuffer.readLine() ) != null ) {
                    reponse=reponse+line;
                }
            } catch (IOException e) {
     
            }
     
            return reponse;
        }

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Août 2005
    Messages
    411
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2005
    Messages : 411
    Par défaut
    effectivement, j'ai un peu changé le code, ca va mieux...


    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
        public String GetStdOutData ()
        {
            char buffer[] = new char[2048];
            int len = 0;
            try
            {
                len = p_outReader.read(buffer, 0, 2048);
                p_outReader.close();
            }
            catch(Exception e)
            {
                e.printStackTrace();
                return null;
            }
     
            return new String (buffer, 0, len);
     
        }
    mais par contre, ca ne lit qu'une seule partie du stdout.

    comment faire pour que ca lise l'ensemble du contenu du buffer svp ?

    merci

  4. #4
    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
    J'aurais plutôt vu quelque chose comme cela :
    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
        try {
            StringBuffer buffer = new StringBuffer();
            BufferedReader reader = new BufferedReader (InputStreamReader(process.getInputStream()));
            try {
                String line; 
                while ( ( line = reader.readLine() ) != null ) {
                    buffer.append(line);
                        }
                }
            } finally {
                reader.close();
            }
            String reponse = buffer.toString();
        } catch(IOException e) {
            e.printStackTrace();
        }
    En plus il faut faire attention à lire le stderr dans un thread séparé pour éviter les interblocages (sujets déjà traités plusieurs fois sur le forum).


    a++

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Août 2005
    Messages
    411
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2005
    Messages : 411
    Par défaut
    Citation Envoyé par adiGuba
    J'aurais plutôt vu quelque chose comme cela :
    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
        try {
            StringBuffer buffer = new StringBuffer();
            BufferedReader reader = new BufferedReader (InputStreamReader(process.getInputStream()));
            try {
                String line; 
                while ( ( line = reader.readLine() ) != null ) {
                    buffer.append(line);
                        }
                }
            } finally {
                reader.close();
            }
            String reponse = buffer.toString();
        } catch(IOException e) {
            e.printStackTrace();
        }
    En plus il faut faire attention à lire le stderr dans un thread séparé pour éviter les interblocages (sujets déjà traités plusieurs fois sur le forum).


    a++
    j'ai pas traité le stderr mais le code que tu m'a donné ne fonctionne pas : meme problème que le premiere code, pas de réponse : il boucle infiniment peut etre....

  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 youp_db
    j'ai pas traité le stderr mais le code que tu m'a donné ne fonctionne pas : meme problème que le premiere code, pas de réponse : il boucle infiniment peut etre....
    Justement : quel est le problème exact ??? Tu n'as pas de message d'erreur ? quel programme est-ce que tu lances ? Enfin si tu ne lis pas le stderr comment pourrait tu savoir s'il y a une erreur ou pas...

    a++

  7. #7
    Membre Expert
    Avatar de professeur shadoko
    Homme Profil pro
    retraité nostalgique Java SE
    Inscrit en
    Juillet 2006
    Messages
    1 257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 76
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : retraité nostalgique Java SE

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 257
    Par défaut
    Citation Envoyé par adiGuba
    [*]La concaténation de String avec l'opérateur + est vraiment très "lourd", il vaut mieux utiliser un StringBuffer/StringBuilder...
    ah pour une fois je ne suis pas d'accord avec AdiGuba....
    pourquoi? parceque le code généré par le compilateur avec la concaténation de chaîne est une manipulation de StringBuffer/StringBuilder. L'avantage même est que ceux qui n'ont pas mis "en dur" StringBuffer ont eu gratuitment StringBuilder en 1.5.
    (bémol: dans certains cas on est quand même plus malin que le compilo mais souvent c'est pas la peine de se casser la tête: pour s'en convaincre regarder le code binaire généré).

  8. #8
    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 professeur shadoko
    ah pour une fois je ne suis pas d'accord avec AdiGuba....


    Et pourtant on est ici dans un cas où le compilateur produit un code ignoble


    Reprenons le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        String line; 
        while ( ( line = stdoutBuffer.readLine() ) != null ) {
            reponse=reponse+line;
        }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        String line; 
        while ( ( line = stdoutBuffer.readLine() ) != null ) {
            reponse = new StringBuilder(reponse).append(line).toString();
        }
    Du coups à chaque itération on crée un nouveau StringBuffer/StringBuilder (new) de la taille de la chaine précédemment lu, auquel tu ajoutes la ligne courante, pour enfin retransformer le tout en String...

    Ce qui te fait allouer deux nouveaux objets et "libérer" deux références pour chaque itération...


    Bien sûr si tu as un un très petit nombre d'itération la différence est minime... mais sinon cela pourrait être énorme...

    Essaye ce code pour le vérifier en vrai :
    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
    27
    28
    29
    30
    31
    32
            final int MAX = 1000;
            String line = "Une phrase de quelques caractères à lire plusieurs fois...\n";
            long start, end;
     
     
            start = System.currentTimeMillis();
            StringBuffer buffer = new StringBuffer();
            for (int i=0; i<MAX; i++) {
                buffer.append(line);
            }
            String bufferStr = buffer.toString();
            end = System.currentTimeMillis();
            System.out.println("StringBuffer      : " + (end-start));
     
     
            start = System.currentTimeMillis();
            StringBuilder builder = new StringBuilder();
            for (int i=0; i<MAX; i++) {
                builder.append(line);
            }
            String builderStr = builder.toString();
            end = System.currentTimeMillis();
            System.out.println("StringBuilder     : " + (end-start));
     
     
            start = System.currentTimeMillis();
            String str = "";
            for (int i=0; i<MAX; i++) {
                str = str + line;
            }
            end = System.currentTimeMillis();
            System.out.println("Concaténation     : " + (end-start));
    N'hésite pas à augmenter la valeur de MAX pour mieux voir le problème

    Perso chez moi avec 1000 cela me donne ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    StringBuffer      : 16
    StringBuilder     : 0
    Concaténation     : 1828
    Et avec 10000 lignes (ce qui ne serait pas vraiment énorme en soit pour la lecture d'un fichier par exemple), la version avec + dépasse les 2 minutes alors que c'est quasiment instantanné pour les deux autres versions :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    StringBuffer      : 47
    StringBuilder     : 46
    Concaténation     : 131157
    a++

  9. #9
    Membre Expert
    Avatar de professeur shadoko
    Homme Profil pro
    retraité nostalgique Java SE
    Inscrit en
    Juillet 2006
    Messages
    1 257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 76
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : retraité nostalgique Java SE

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 257
    Par défaut
    edffectivement j'ai revérifié!
    j'avais fait un test équivalent il y a longtemps et le code généré prenait un seul StringBuffer et concatenait à chaque iteration.
    regression? (ou mémoire défaillante de ma part?)

  10. #10
    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 professeur shadoko
    regression? (ou mémoire défaillante de ma part?)
    Mémoire défaillante


    Plus sérieusement je pense que tu dois confondres avec le cas suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    String str = object1 + " : " + object2 + " : " + 15 + " : " object3 + " : " + object4 + ".";
    Qui utilise bien un et un seul StringBuffer de manière optimal :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    String str = new StringBuffer().append(object1)
        .append(" : ").append(object2)
        .append(" : 15 : ").append(object3)
        .append(" : ").append(object4)
        .append(".").toString();
    Dans ce cas là il est bien entendu complètement inutile d'utiliser le StringBuffer car pour le même résultat l'opérateur + est bien plus lisible et tout aussi performant...

    A noter également que dans ce cas là le compilateur peut concaténer les constantes dès la compilation (" : " + 15 + " : " qui devient " : 15 : ").

    a++

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

Discussions similaires

  1. [PERL] Problème lecture/écriture dans un fichier
    Par LE NEINDRE dans le forum Langage
    Réponses: 4
    Dernier message: 17/08/2005, 13h15
  2. [SAX] Problème lecture fichier xml
    Par BernardT dans le forum Format d'échange (XML, JSON...)
    Réponses: 3
    Dernier message: 07/07/2005, 18h11
  3. [communication série] problème lecture/écriture
    Par davinout dans le forum API, COM et SDKs
    Réponses: 9
    Dernier message: 01/06/2005, 13h14
  4. Problème lecture fichier en C++
    Par cali1983 dans le forum C++
    Réponses: 17
    Dernier message: 20/05/2005, 09h36
  5. Problème lecture de nombre dans un fichier en c++
    Par knecmotet dans le forum C++
    Réponses: 1
    Dernier message: 28/10/2004, 15h48

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