Devilmarkus Geschrieben 10. Mai 2010 Teilen Geschrieben 10. Mai 2010 Hallo, ich habe folgende Frage: Mit dem Befehl Runtime.getRuntime().exec(String command); kann ich ja eine Anwendung ausführen. Ist es auch möglich, wenn diese Anwendung etwas in die DOS-Konsole schreibt, dieses abzufangen und in ein Java-Textfield zu schreiben? Wäre super wenn mir jemand sagen könnte, ob und wie das geht. Gruss, Markus Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
perdian Geschrieben 10. Mai 2010 Teilen Geschrieben 10. Mai 2010 exec liefert dir ein Process Objekt zurück, wodurch die an stdout und stderr der Anwendung kommt. Diese kannst du auslesen und beliebig weiterverarbeiten. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Devilmarkus Geschrieben 10. Mai 2010 Autor Teilen Geschrieben 10. Mai 2010 Nun... ich versuche es nun so: protected void launch(String command) { try { convertStreamToString(Runtime.getRuntime().exec(command).getInputStream()); } catch (Exception e) { } } protected void convertStreamToString(InputStream is) throws IOException { if (is != null) { StringBuilder sb = new StringBuilder(); String line; try { BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8")); while ((line = reader.readLine()) != null) { sb.append(line).append("\r\n"); text.append(sb.toString()); System.out.println("running..."); } } finally { is.close(); } text.setText(sb.toString()); } else { text.setText("Error\r\n"); } } private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { Thread runner = new Thread() { public void run() { launch("tools/SamDisk.exe test.dsk a: -h0"); } }; runner.start(); } Wobei "text" eine "TextArea" ist... Das Problem hier ist: Er zeigt mir nur beim Start kurz eine Meldung an. Das Programm aber liefert, während es läuft, Informationen an die DOS-Konsole. (Es beschreibt/liest Disketten und gibt währenddessen die Track Informationen aus) Jemand eine Idee, was ich ändern kann, damit ich 'während' der gesamte DOS-Prozess läuft, die Informationen erhalte? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
smash Geschrieben 10. Mai 2010 Teilen Geschrieben 10. Mai 2010 Ich glaube der InputStream darf nicht geschlossen werden. Du willst ja schließlich auch später noch Ausgaben weiterverarbeiten, auch wenn es einen Zeitpunkt gibt, zu dem gerade keine Daten hereinkommen. Ich sehe drei Ansätze das Problem zu lösen: Immer wieder prüfen ob der Stream etwas geliefert hat. Z. B. mit einer Endlosschleife in einem eigenen Thread.Wäre natürlich super, wenn der Stream sich melden würde, wenn Daten vorliegen. Keine Ahnung ob es da schon was etwas im JDK gibt (so was wie ein Listener).Vielleicht gibt es auch schon etwas um ein Textfield / Textarea mit einem Stream zu koppeln. Bei den ersten zwei Varianten müsstest du selber dafür sorgen, dass hereinkommende Daten in das Textfeld geschrieben werden. Außerdem müsste der Stream vor dem Programmende geschlossen werden. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
smash Geschrieben 10. Mai 2010 Teilen Geschrieben 10. Mai 2010 G00gl3 mal nach jtextarea + outputstream oder jtextarea + inputstream. Hab auf anhieb ein paar interessante Seiten gefunden. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Devilmarkus Geschrieben 10. Mai 2010 Autor Teilen Geschrieben 10. Mai 2010 Also ich habe nun Folgendes: protected Process process; public void Launch(boolean direction) throws InterruptedException, IOException { String file = null; if (direction) { FileDialog filedia = new FileDialog((Frame) new Frame(), "Create DSK file", FileDialog.SAVE); filedia.setFile("*.dsk"); filedia.setVisible(true); String filename = filedia.getFile(); if (filename != null) { filename = filedia.getDirectory() + filedia.getFile(); file = filename; } } else { FileDialog filedia = new FileDialog((Frame) new Frame(), "Open DSK file", FileDialog.LOAD); filedia.setFile("*.dsk"); filedia.setVisible(true); String filename = filedia.getFile(); if (filename != null) { filename = filedia.getDirectory() + filedia.getFile(); file = filename; } } if (file == null) { return; } text.setText("SAMdisk GUI 1.0 (May 10 2010), by Markus Hohmann -- http://cpc-live.com/\r\n"); text.append("SAMdisk 3.0 (Jun 2 2009), by Simon Owen -- http://simonowen.com/samdisk/\r\n"); String ending = ""; if (!heads.isSelected()) { ending = "-h0"; } String drv = "a:"; String command = ""; if (gaps.isSelected()) { ending = ending + " --gaps"; } if (direction) { command = drv + " \"" + file + "\" " + ending; } else { command = "\"" + file + "\" " + drv + " " + ending; } process = Runtime.getRuntime().exec("tools/SamDisk.exe " + command); text.append("SamDisk.exe " + command + "\r\n"); text.select(20000000, 20000000); InputStream is = process.getInputStream(); InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr); String line; jButton1.setEnabled(false); jButton2.setEnabled(true); progress.setIndeterminate(true); while ((line = br.readLine()) != null) { if (line != null) { text.append(line + "\r\n"); text.select(20000000, 20000000); } } br.close(); text.append("Done...\r\n"); text.select(20000000, 20000000); progress.setIndeterminate(false); jButton1.setEnabled(true); jButton2.setEnabled(false); prog = 0; process = null; } Das Problem: Fehlermeldungen und so spuckt diese Funktion aus. Beispiel: (Ausgabe in JTextField): 42 Tracks, Head 0 Dann werkelt er und findet dabei einen Fehler: Failed to read sector XX Wenns beendet ist: Done... Das Problem ist aber: Während das DOS Programm arbeitet, hat es eine Anzeige, was es grad tut.. Beispiel: Reading Track 6 Head 0 (Steigert sich dann je nach Fortschritt, bis zum Ende) Dieses wird nicht in dem JTextField angezeigt *grummel* Eventuell ist das ein OutputStream? Wenn ja, wie kann ich diesen Abfangen? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
smash Geschrieben 13. Mai 2010 Teilen Geschrieben 13. Mai 2010 Also erstmal hat du ja den InputStream. Durch den InputStream kommen die Ausgaben des anderen Programms in dein Java Programm. Jetzt müssen diese Daten weiterverarbeitet bzw. Ausgegeben werden. Ansätze dafür hatte ich in meinem ersten Beitrag genannt. In deinem Code wird der BufferedReader geschlossen, wenn keine neuen Daten vorliegen. Der Reader sollte nicht geschlossen werden, wenn gerade keine Daten vorliegen, denn das andere Programm kann ja zu einem späteren Zeitpunkt neue Daten ausgeben. Der Reader sollte erst geschlossen werden, wenn das andere Programm beendet wurde! Ich hab just mal ne Klasse geschrieben, die einen InputStream in einen OutputStreamWriter umleitet. Hier könntest du dir anschauen, wie man dann einen OutputStream baut, der etwas in ein JTextArea ausgibt. Ich denke damit müsstest du weiterkommen. Ansonsten noch nachfragen. Kann auch sein, dass man da noch was optimieren kann. Das sollte aber nur nötig sein, wenn dein Programm viele Ausgaben liefert. Ich halte es für wahrscheinlicher, dass man den Listener in einem eigenen Thread laufen lassen sollte. Ich würds aber erstmal so probieren. Ich habe den Code nicht getestet. import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; public class CharInputStreamListener { private OutputStreamWriter outputStream; private BufferedReader reader; private boolean run; public CharInputStreamListener(InputStream inputStream, OutputStreamWriter outputStream) { this.reader = new BufferedReader(new InputStreamReader(inputStream)); this.outputStream = outputStream; run = true; listen(); } private void listen(){ try { while(run){ int data = getReader().read(); if(data != -1){ getOutputStream().write(data); } } } catch (IOException e) { e.printStackTrace(); } } public BufferedReader getReader() { return reader; } public boolean run() { return run; } public void run(boolean run) { this.run = run; } public OutputStreamWriter getOutputStream() { return outputStream; } } Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.