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 :

[Runtime][exec]Récupérer les stdout ET stderr


Sujet :

API standards et tierces Java

  1. #1
    Membre régulier
    Homme Profil pro
    SAP BC Admin
    Inscrit en
    Août 2004
    Messages
    75
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : Belgique

    Informations professionnelles :
    Activité : SAP BC Admin
    Secteur : Finance

    Informations forums :
    Inscription : Août 2004
    Messages : 75
    Points : 119
    Points
    119
    Par défaut [Runtime][exec]Récupérer les stdout ET stderr
    Hello,

    j'ai une petite question et une réponse, mais je ne suis pas certain que ma solution est optimale.

    Je lance un process qui produit des outputs + ou - important dans les stderr et stdout. J'ai bien trouvé sur la FAQ des réponses pour récupérer les Streams, mais on ne fait que lire tout un Stream et puis ensuite tout le 2e. Si le buffer du 2e est à un moment plein, le process est bloqué et le programme ne se stoppe pas. Ma solution, 2 Threads. Je ne sais pas si c'est la bonne méthode. Si quelqu'un pouvez-vous m'éclairer: me dire si c'est bien, pas bien ou comment je peux améliorer les choses ...

    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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    package monpackage;
     
    import java.io.IOException;
    import java.io.InputStream;
     
    public class Main {
    	class MyThread extends Thread {
    		private StringBuffer buf;
     
    		private InputStream in;
     
    		public MyThread(StringBuffer buf, InputStream in) {
    			this.buf = buf;
    			this.in = in;
    		}
     
    		public void run() {
    			synchronized (buf) {
    				int b = 0;
    				try {
    					while ((b = in.read()) != -1) {
    						buf.append((char) b);
    					}
    				} catch (IOException e) {
    					e.printStackTrace();
    				}
    			}
    		}
    	};
     
    	private volatile boolean running;
     
    	public static void main(String[] args) throws IOException,
    			InterruptedException {
    		new Main();
    	}
     
    	public Main() throws IOException, InterruptedException {
    		final StringBuffer outBuf = new StringBuffer();
    		final StringBuffer errBuf = new StringBuffer();
    		Process process = null;
    		try {
    			process = Runtime.getRuntime().exec("cmd /c dir /s");
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    		final InputStream out = process.getInputStream();
    		final InputStream err = process.getErrorStream();
    		MyThread readOutThread = new MyThread(outBuf, out);
    		MyThread readErrThread = new MyThread(errBuf, err);
     
    		process.getOutputStream().close();
    		readErrThread.start();
    		readOutThread.start();
     
    		process.waitFor();
     
    		synchronized (outBuf) {
    			out.close();
    		}
    		synchronized (errBuf) {
    			err.close();
    		}
     
    		System.out.print(outBuf.toString());
    		System.err.print(errBuf.toString());
    		System.out.println("Process RC: " + process.exitValue());
    	}
    }
    Dans ce cas, c'est un dir tout simple, mais normalement, je dois exécuter un programme sur lequel je n'ai pas de contrôle (acheté).

    Merci

  2. #2
    Membre régulier
    Homme Profil pro
    SAP BC Admin
    Inscrit en
    Août 2004
    Messages
    75
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : Belgique

    Informations professionnelles :
    Activité : SAP BC Admin
    Secteur : Finance

    Informations forums :
    Inscription : Août 2004
    Messages : 75
    Points : 119
    Points
    119
    Par défaut
    J'ai fait une autre version et j'ai maintenant une question. Comment synchronisé les accès sur la list ? Dans la version posté ci-dessous, j'attends que le process se termine (waitFor), mais j'aimerai pouvoir lire les Strings de la list pendant que la liste se rempli. Une idée ? Important, je suis en Java 1.4.2.

    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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    package monpackage;
     
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.util.Collections;
    import java.util.Iterator;
    import java.util.LinkedList;
    import java.util.List;
     
    public class Main {
    	class MyThread extends Thread {
    		private List list;
     
    		private InputStream in;
     
    		public MyThread(List list, InputStream in) {
    			this.in = in;
    			this.list = list;
    		}
     
    		public void run() {
    			BufferedReader br = new BufferedReader(new InputStreamReader(in));
    			String s;
    			try {
    				while ((s = br.readLine()) != null) {
    					list.add(s);
    				}
    				in.close();
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    		}
    	};
     
    	public static void main(String[] args) throws IOException,
    			InterruptedException {
    		new Main();
    	}
     
    	public Main() throws IOException, InterruptedException {
    		Process process = null;
    		try {
    			process = Runtime.getRuntime().exec("cmd /c dir /s");
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    		InputStream out = process.getInputStream();
    		InputStream err = process.getErrorStream();
    		List list = Collections.synchronizedList(new LinkedList());
     
    		MyThread readOutThread = new MyThread(list, out);
    		MyThread readErrThread = new MyThread(list, err);
     
    		process.getOutputStream().close();
    		readErrThread.start();
    		readOutThread.start();
     
    		process.waitFor();
     
    		Iterator it = list.iterator();
    		while (it.hasNext()) {
    			System.out.println((String) it.next());
    		}
     
    		System.out.println("Process RC: " + process.exitValue());
    	}
    }

  3. #3
    Membre régulier
    Homme Profil pro
    SAP BC Admin
    Inscrit en
    Août 2004
    Messages
    75
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : Belgique

    Informations professionnelles :
    Activité : SAP BC Admin
    Secteur : Finance

    Informations forums :
    Inscription : Août 2004
    Messages : 75
    Points : 119
    Points
    119
    Par défaut
    Bon, je vois que ce sujet ne passionne pas les foules. J'ai trouvé où conceptuellement, je faisais fausse route (sans savoir si je n'ai pas réinventé la roue). Voici la dernière version du code de lecture. Ici, je fais un mix des Stdout et Stderr pour ne rien loupé et ne pas être bloqué.

    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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    package monpackage;
     
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.util.Collections;
    import java.util.LinkedList;
    import java.util.List;
     
    public class Main {
    	class MyBuffer {
    		private List list;
     
    		private int nbConnected;
     
    		public MyBuffer() {
    			list = Collections.synchronizedList(new LinkedList());
    			nbConnected = 0;
    		}
     
    		public void add(String s) {
    			synchronized (list) {
    				list.add(s);
    				list.notify();
    			}
    		}
     
    		public String get() {
    			System.err.flush();
    			String s;
    			synchronized (list) {
    				if (list.size() == 0) {
    					try {
    						list.wait();
    					} catch (InterruptedException e) {
    						e.printStackTrace();
    					}
    				}
    				s = (String) list.remove(0);
    			}
    			return s;
    		}
     
    		public void connect() {
    			nbConnected++;
    		}
     
    		public void disconnect() {
    			nbConnected--;
    			if (nbConnected == 0) {
    				add(null);
    			}
    		}
    	}
     
    	class MyThread extends Thread {
    		private MyBuffer buffer;
     
    		private InputStream in;
     
    		public MyThread(MyBuffer buffer, InputStream in) {
    			this.in = in;
    			this.buffer = buffer;
    			buffer.connect();
    		}
     
    		public void run() {
    			BufferedReader br = new BufferedReader(new InputStreamReader(in));
    			String s;
    			try {
    				while ((s = br.readLine()) != null) {
    					buffer.add(s);
    				}
    				in.close();
    				buffer.disconnect();
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    		}
    	};
     
    	public static void main(String[] args) throws IOException,
    			InterruptedException {
    		new Main();
    	}
     
    	public Main() throws InterruptedException {
    		Process process = null;
    		try {
    			process = Runtime.getRuntime().exec("cmd /c dir /s");
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    		InputStream out = process.getInputStream();
    		InputStream err = process.getErrorStream();
     
    		MyBuffer buffer = new MyBuffer();
    		MyThread readOutThread = new MyThread(buffer, out);
    		MyThread readErrThread = new MyThread(buffer, err);
     
    		try {
    			process.getOutputStream().close();
    		} catch (IOException e2) {
    			e2.printStackTrace();
    		}
     
    		readErrThread.start();
    		readOutThread.start();
     
    		String s;
    		while ((s = buffer.get()) != null) {
    			System.out.println(s);
    		}
     
    		System.out.println("Process RC: " + process.exitValue());
    	}
    }
    N'hésitez pas à faire vos remarques. Quand même.

    Merci

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

Discussions similaires

  1. [RUNTIME][EXEC]
    Par adrien1977 dans le forum API standards et tierces
    Réponses: 7
    Dernier message: 30/09/2009, 16h28
  2. Réponses: 15
    Dernier message: 21/02/2007, 17h29
  3. [Servlet][Windows][System call]Runtime.exec
    Par lucho31 dans le forum Servlets/JSP
    Réponses: 8
    Dernier message: 18/01/2005, 11h55
  4. Réponses: 2
    Dernier message: 05/10/2004, 22h43
  5. [Système][Runtime][Exec] Comportement étrange au lancement de BeSweet
    Par divxdede dans le forum API standards et tierces
    Réponses: 1
    Dernier message: 06/06/2004, 09h54

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