[JAVA] Runtime.getRuntime().exec probleempje

Pagina: 1
Acties:
  • 114 views sinds 30-01-2008
  • Reageer

  • FoxMan
  • Registratie: September 2000
  • Laatst online: 21-08-2025
Ik ben bezig met het maken van een frontend voor Mame (een arcade emulator (of beter DE arcade emulator)) in JAVA. Hiervoor moet ik natuurlijk het programma aanroepen vanuit mijn JAVA programma, dit is opzich niet zo'n probleem, want dat lukt goed. Maar er zit ook een leuke functie in Mame, speciaal voor frontends, een methode om te testen of de roms die in een bepaalde directory staan wel compleet/volledig zijn. Als ik deze dit vanuit een gewone console doe (in DOS-prompje intyp "mame -rompath dir/naar/roms -verifysets" krijg ik de uitvoer, maar als ik het in mijn JAVA programmaatje probeer met

code:
1
2
3
4
5
6
7
Process p=Runtime.getRuntime().exec("mame -rompath dir/naar/roms -verifysets");
BufferedReader input=new BufferedReader(new InputStreamReader(p.getInputStream()));
while((line=input.readLine())!=null)
{
  System.out.println(line);
}
input.close();


krijg ik niets.
Ik denk dat het ermee te maken heeft dat Mame er misschien te lang over doet om de roms te checken, want als ik het zelfde doe met een ander commando (bijv "mame -list" om een lijst van alle ondersteunde roms weer te geven) lukt het wel.
Ik heb het ook al geprobeerd met "cmd /c mame -rompath dir/naar/roms -verifysets", dit werkt ook niet. En een Thread.sleep() ertussen zetten werkt ook niet.

LinuxFox, because penguins aren't even furry


  • CyBoB
  • Registratie: Januari 2001
  • Laatst online: 24-12-2025

CyBoB

.::BURB::.

probeer dezelfde code eens maar dan met het verkrijgen van de ErrorStream? dus ipv p.getInputStream() p.getErrorStream() !?!?

sommige proggie schrijven daar namelijk hun output naar toe.

  • pgussow
  • Registratie: Maart 2003
  • Laatst online: 18-08-2025
En wat gebeurd er als je het commando "mame -rompath dir/naar/roms -verifysets" in je 'normale' cmd execute?

Verwijderd

effe kort:

uit de call naar exec() krijg je een Process object, hier moet je een waitFor() op loslaten...

zie http://java.sun.com/j2se/...ng/Process.html#waitFor()

  • FoxMan
  • Registratie: September 2000
  • Laatst online: 21-08-2025
CyBoB schreef op 12 June 2003 @ 18:59:
probeer dezelfde code eens maar dan met het verkrijgen van de ErrorStream? dus ipv p.getInputStream() p.getErrorStream() !?!?

sommige proggie schrijven daar namelijk hun output naar toe.
Ik zal dit eens proberen en zal hier zo posten wat de uitvoer is hiervan (als er uitvoer is :P)
pgussow schreef op 13 juni 2003 @ 08:04:
En wat gebeurd er als je het commando "mame -rompath dir/naar/roms -verifysets" in je 'normale' cmd execute?
Als ik dat doe krijg ik een lijstje met roms die goed en slecht zijn..
Verwijderd schreef op 13 juni 2003 @ 08:49:
effe kort:

uit de call naar exec() krijg je een Process object, hier moet je een waitFor() op loslaten...

zie http://java.sun.com/j2se/...ng/Process.html#waitFor()
Dit zal niet werken, want dan krijg je zeker geen uitvoer, maar dan wordt het alleen uitgevoerd..
waitFor

public abstract int waitFor()
throws InterruptedException

causes the current thread to wait, if necessary, until the process represented by this Process object has terminated. This method returns immediately if the subprocess has already terminated. If the subprocess has not yet terminated, the calling thread will be blocked until the subprocess exits.

Returns:
the exit value of the process. By convention, 0 indicates normal termination.
Throws:
InterruptedException - if the current thread is interrupted by another thread while it is waiting, then the wait is ended and an InterruptedException is thrown.

LinuxFox, because penguins aren't even furry


  • Glimi
  • Registratie: Augustus 2000
  • Niet online

Glimi

Designer Drugs

(overleden)
FoxMan schreef op 13 June 2003 @ 09:11:
Dit zal niet werken, want dan krijg je zeker geen uitvoer, maar dan wordt het alleen uitgevoerd..
Waarom zou je geen uitvoer krijgen? Het staat gewoon in de inputbuffer hoor?

Verwijderd

Je hoeft alleen een p.waitFor() te plaatsen voor de while.
Zorg wel dat je al een BufferedReader heb gekoppeld aan de out en error, anders kan hij z'n output niet kwijt en zal het process blijven hangen.

  • FoxMan
  • Registratie: September 2000
  • Laatst online: 21-08-2025
Ik heb het geprobeerd met de ErrorStream en dit werkt half.
Ik zal even uitleggen wat de normale uitvoer van het programmaatje is:
Het programmaatje begint met kijken of de eerste rom goed of slecht is, dit laat hij zien met procenten, het gaat allemaal heel snel, dus wachten is er haast niet bij. Ik heb de uitvoer even snel kunnen stoppen met pauze en het zag er zo uit:
code:
1
2
3
4
5
romset ckong is bad
romset ckonga [ckong] is bad
romset rallyx is good
romset rallyxm [rallyx] is good
22%


Nu krijg ik wel een hele lijst met procenten te zien met de Errorstream, maar ik krijg de regels waarop staat of de rom goed of slecht is niet te zien...

LinuxFox, because penguins aren't even furry


  • FoxMan
  • Registratie: September 2000
  • Laatst online: 21-08-2025
Verwijderd schreef op 13 juni 2003 @ 09:25:
Je hoeft alleen een p.waitFor() te plaatsen voor de while.
Zorg wel dat je al een BufferedReader heb gekoppeld aan de out en error, anders kan hij z'n output niet kwijt en zal het process blijven hangen.
Je bedoeld op deze manier?:

code:
1
2
3
4
5
6
7
8
BufferedReader errorRdr=new BufferedReader(new InputStreamReader(p.getErrorStream()));
BufferedReader inputRdr=new BufferedReader(new InputStreamReader (p.getInputStream()));
p.waitFor();

while((line=inputRdr.readLine())!=null)
{
   System.out.println(line);
}


Want hetgene wat hierboven staat werkt niet :(.

LinuxFox, because penguins aren't even furry


Verwijderd

RAAARRRRR

Ik zou verwachten dat dat werkt.

Je leest in het bovenstaande de error niet uit.
Je kan de twee streams ook tegelijkertijd uitlezen met twee aparte threads.
Die kan je weer in dezelfde buffer laten schrijven.
Misschien dat dat beter werkt omdat je dan de stream eerder uitleest...
De threads start je dan net voor de waitFor.

Voorbeeld van de run method voor de thread:
code:
1
2
3
4
5
6
7
8
9
public void run() {
     int b;
     try {
          while ((b = processOutput.read()) != -1)
               System.out.print ((char)b);
     } catch (IOException e) {
          errorMessage = "Error by reading process output: " + e.toString();
     }
}

  • FoxMan
  • Registratie: September 2000
  • Laatst online: 21-08-2025
Verwijderd schreef op 13 June 2003 @ 10:02:
RAAARRRRR

Ik zou verwachten dat dat werkt.

Je leest in het bovenstaande de error niet uit.
Je kan de twee streams ook tegelijkertijd uitlezen met twee aparte threads.
Die kan je weer in dezelfde buffer laten schrijven.
Misschien dat dat beter werkt omdat je dan de stream eerder uitleest...
De threads start je dan net voor de waitFor.

Voorbeeld van de run method voor de thread:
code:
1
2
3
4
5
6
7
8
9
public void run() {
     int b;
     try {
          while ((b = processOutput.read()) != -1)
               System.out.print ((char)b);
     } catch (IOException e) {
          errorMessage = "Error by reading process output: " + e.toString();
     }
}
Bedankt voor de tip, maar ik ben er uit, ik heb het nu zo:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
BufferedReader errorRdr=new BufferedReader(new InputStreamReader(p.getErrorStream()));
BufferedReader inputRdr=new BufferedReader(new InputStreamReader (p.getInputStream()));

while((line=errorRdr.readLine())!=null)
{
   System.out.println(line);
}


p.waitFor();

while((line=inputRdr.readLine())!=null)
{
   System.out.println(line);
}


En het werkt :)

Kan iemand dit verklaren? (Als ik p.waitFor() voor de errorRdr.readLine() werkt het niet... en achter de inputRdr.readLine() werkt het wel weer..)

LinuxFox, because penguins aren't even furry


Verwijderd

Een mogelijke verklaring zou kunnen zijn dat je de streams echt uit moet lezen zodra er wat in staat. Ik heb een keer gehad dat het process bleef hangen omdat het de output niet kwijt kan.

Als dat waar is werkt jou code alleen in dit geval waarin je "teveel" error output en "niet teveel" standard output hebt. Krijg je meer standard ouput dat gaat hij daar op hangen.
Ik zou voor de oplossing gaan waarbij je 2 threads hebt die parallel de streams uitlezen.
Dan kan je dat probleem nooit krijgen. Ik de link die ik eerder postte staat aardige voorbeeldcode.

Je kan het natuurlijk even testen door een procesje te maken dat veel error en standard uitprint. Ik heb trouwens ook gemerkt dat het per OS verschilt hoeveel output een process kan hebben voordat het blijft hangen (andere grote van de tijdelijke outputbuffers...).

  • FoxMan
  • Registratie: September 2000
  • Laatst online: 21-08-2025
Bedankt voor de tips, ik denk dat ik ze dan toch in 2 aparte threads zal laten uitlezen. Het testen op een ander OS is op dit moment alleen nog niet mogelijk, ik zal het over een week of 3 of 4 eens proberen op mijn eigen PC onder Debian ipv Windows.

LinuxFox, because penguins aren't even furry

Pagina: 1