Hi all,
Je suis en train de travailler sur librairie de scripting pour Scala (http://www.scala-lang.org/). Pour ceux qui ne connaissent pas ce language, Scala est un language fonctionnel et OO qui utilise directement java. Il est donc possible d'écrire du Java avec du scala (d'où ma présence sur ce forum).
Je dois implémenter les opérations standard du shell (>,|,<,||,&&,...) afin de pouvoir utiliser Scala comme un language de scripting. J'utilise donc les classes ProcessBuilder et Process.
Voilà pour le background.
J'ai cependant un problème relativement coriace pour les pipes : il faut rediriger la sortie du premier process vers l'entrée du deuxième process. Ca marche nickel pour un premier process qui se termine, car je peux fermer l'outputstream du deuxième. Cependant, pour un premier process qui ne s'arrête jamais (typiquement, "tail -f file"), je ne peux pas fermer l'outputStream du deuxième (évidemment). J'essaie vainement de flusher l'outputstream, mais le deuxième process reçoit les données en entrée que lorsqu'une certaine quantité y a été écrite (environ 900bytes). Ceci n'est pas acceptable pour un progamme du type "tail -f file" qui renvoit que très peu de données.
Voici un example de code (en Java) qui caractérise bien ce que j'essaie de faire :
Ca sent furieusement l'outputStream bufferisé. Pour m'en assurer, j'ai été voir l'implémentation directement dans le source code java, et effectivement, on reçoit bien un BufferedOutputStream lorsque l'on appelle getOutputStream d'un Process. Alors pourquoi ça ne flush pas correctement? Ai-je oublié quelque chose de fondamental? Est-ce normal?
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 proc1 = Runtime.getRuntime().exec("tail -f file"); proc2 = Runtime.getRuntime().exec("grep pattern"); br1 = new BufferedInputStream(proc1.getInputStream()); br2 = new BufferedInputStream(proc2.getInputStream()); out = proc2.getOutputStream(); // Thread for reading output of process2 new Thread (){ public void run () { int read = -1; byte[] buffer = new byte[1]; try { while ((read = br2.read(buffer)) != -1) { System.out.write(buffer, 0, read); System.out.flush(); } br2.close(); } catch (IOException ex) { // Handle exception } } }.start(); byte[] buffer = new byte[1]; // Should be greater (just for demo here) int read = -1; // Read output of process1 and feed input of process2 with while ((read = br1.read(buffer)) != -1) { out.write(buffer,0,read); out.flush(); //Should flush, wtf?? } out.close(); br1.close(); proc1.waitFor(); proc2.waitFor();
Merci pour votre aide :-)
System :
java version "1.6.0_06"
Java(TM) SE Runtime Environment (build 1.6.0_06-b02)
Java HotSpot(TM) 64-Bit Server VM (build 10.0-b22, mixed mode)
Linux 2.6.24-gentoo-r7 x86_64 Intel(R) Core(TM)2 Duo CPU E6750 @ 2.66GHz GenuineIntel GNU/Linux
Alexandre Roux
Partager