Zum Inhalt springen

Umleitung einer DOS Anwendung in Java Applikation


Empfohlene Beiträge

Geschrieben

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

Geschrieben

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?

Geschrieben

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:

  1. Immer wieder prüfen ob der Stream etwas geliefert hat. Z. B. mit einer Endlosschleife in einem eigenen Thread.
  2. 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).
  3. 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.

Geschrieben

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?

Geschrieben

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;

	}


}

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.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...