1. Schnittstellen zum Betriebssystem
Java-Entwicklern fällt oft nicht auf, wie viel die Java-Bibliotheken vom Betriebssystem wegabstrahieren. Ein paar Beispiele: Java setzt automatisch bei Pfadangaben den korrekten Pfadseparator (/
oder \
) und bei Zeilenumbrüchen automatisch das übliche Zeilenendezeichen des Betriebssystems. Bei der Formatierung für Konsoleneingaben und beim Parsen von Konsoleneingaben greift Java automatisch auf die eingestellte Landessprache des Betriebssystems zurück.
Nicht nur, dass die Java-Bibliothek diese Eigenschaften intern verwendet, sondern sie sind für alle zugänglich. Die Eigenschaften verstecken sich an unterschiedlichen Stellen, etwa:
in den System-Properties
in Platform MXBeans, wie der
OperatingSystemMXBean
mit zum BeispielgetSystemCpuLoad()
in
java.net.NetworkInterface
für Netzwerkkarten und MAC-Adressein
Toolkit
für die Bildschirmauflösungin
GraphicsEnvironment
für die installierten Fonts
Wenn spezielle Informationen fehlen, können Java-Programme externe native Programme aufgerufen und mit ihnen kommunizieren, um zum Beispiel weitere Details zu erfragen. Die Aufgaben in diesem Kapitel konzentrieren sich auf die System-Properties und wie man externe Programme aufrufen kann.
Voraussetzungen
Interaktion mit der Kommandozeile kennen
Umgebungsvariablen auswerten können
Externen Programme starten können
Verwendete Datentypen in diesem Kapitel:
Noch mehr Aufgaben findest du im Buch: ›Captain CiaoCiao erobert Java: Das Trainingsbuch für besseres Java. 300 Java-Workshops, Aufgaben und Übungen mit kommentierten Lösungen‹
1.1. Konsole
Java-Programme bestehen nicht nur aus Algorithmen, sondern sie interagieren mit uns und mit dem Betriebssystem. Zwei der ersten Anweisungen waren System.out.println()
und new Scanner(System.in).next()
— eine Bildschirmausgabe und Konsoleneingabe sind klassische Schnittstellen zwischen Programm und Benutzer.
System.out
und System.err
sind vom Typ PrintStream
, System.in
vom Typ InputStream
. Die Klasse System
hat Methoden um die drei Ströme umzulenken, etwa in Dateien.
1.1.1. Farbige Konsolenausgaben ⭐
Schon in den allerersten Java-Programmen haben wir auf der Konsole Text ausgegeben. Allerdings zeigt die Textausgabe auf System.out
und System.err
den Text einmal in Schwarz, dann in Rot, es gibt also verschiedene Farben.
In dieser Aufgabe wollen wir uns mit der Frage beschäftigen, wie wir selbst farbige Ausgaben schreiben können. Die Lösung dahinter ist, dass Ausgaben mehr als nur Text schreiben. Es gibt besondere Kommandos, die in der Konsole die Farbe ändern, den Cursor bewegen, den Bildschirm löschen usw. Dafür sind ANSI-Escape-Sequenzen verantwortlich; sie starten mit einem Control Sequence Introducer, dem String
\u001B[
und enden mit dem String
m
\u001B
ist im ASCII-Alphabet das ESC
-Zeichen, dezimal 27.
In Java lassen sich Escape-Sequenzen problemlos in den System.out
oder System.err
schreiben, und es gibt Bibliotheken wie zum Beispiel https://github.com/fusesource/jansi, die das über Konstanten und Methoden vereinfachen. Problematisch ist lediglich, dass die unterschiedlichen Konsolen nicht zwangsläufig alle Escape-Sequenzen verstehen. In der Standardeinstellung versteht z. B. die cmd.exe von Windows nichts. Die Unterstützung von einigen Farben ist jedoch bei anderen Konsolen verbreitet:
Schwarz:
\u001B[30m
Rot:
\u001B[31m
Grün:
\u001B[32m
Gelb:
\u001B[33m
Blau:
\u001B[34m
Magenta:
\u001B[35m
Zyan:
\u001B[36m
Weiß:
\u001B[37m
Zurücksetzen:
\u001B[0m
Zur Dekoration eignen sich:
fett:
\u001B[1m
unterstrichen:
\u001B[4m
invertiert:
\u001B[7m
Aufgabe:
Lege eine neue Klasse
AnsiColorHexDumper
an, und setze folgende Konstanten in die Klasse:public static final String ANSI_RED = "\u001B[31m"; public static final String ANSI_GREEN = "\u001B[32m"; public static final String ANSI_BLUE = "\u001B[34m"; public static final String ANSI_PURPLE = "\u001B[35m"; public static final String ANSI_CYAN = "\u001B[36m"; public static final String ANSI_RESET = "\u001B[0m";
Schreibe eine neue Methode
printColorfulHexDump(Path)
, die die übergebene Datei einliest und als Hexdump auf der Konsole ausgibt. Unter einem Hexdump versteht man die Ausgabe einer Datei in Hexadezimalschreibweise, also Folgen wie50 4B 03 04 14 00 06 00 08 00
, die in Spalten geschrieben werden.Erweitere das Programm so, dass Farben das Vorkommen von bestimmten Bytes in der Datei deutlich machen. So können zum Beispiel ASCII-Buchstaben in einer Farbe erscheinen, Ziffern aber wieder in einer anderen.
1.2. Properties
Der Begriff Properties ist in Java mehrfach belegt. Er steht für die JavaBean-Properties und für Schlüssel-Wert-Paare, die zur Konfiguration genutzt werden können. Wenn wir in diesem Kapitel über »Properties« sprechen, sollen immer Schlüssel-Wert-Paare gemeint sein, insbesondere die Paare, die ein Properties
-Objekt verwaltet.
1.2.1. Windows oder Unix oder macOS? ⭐
Die System-Properties enthalten eine Reihe von Informationen, die zum Teil auch über Methoden zugänglich sind. Die Javadoc führt unter https://docs.oracle.com/javase/8/docs/api/java/lang/System.html#getProperties-- die Variablen auf.
Aufgabe:
Lege einen neuen Aufzählungstyp
OS
mit den KonstantenWINDOWS
,MACOS
,UNIX
,UNKNOWN
an.Ergänze eine statische Methode
current()
, die mitSystem.getProperty("os.name")
den Namen des Betriebssystems ausliest und das entsprechende Aufzählungselement als Ergebnis liefert.
1.2.2. Kommandozeilen-Properties und Properties aus Dateien vereinheitlichen ⭐
Properties lassen sich von der Kommandozeile setzen und können so von außen in ein Java-Programm eingeführt werden. Das soll diese Aufgabe trainieren.
Webserver laufen auf unterschiedlichen Ports, im Entwicklungsmodus in der Regel auf 8080.
Aufgabe:
Schreibe ein Programm, das aus unterschiedlichen Quellen die Port-Angaben annehmen kann:
Auf der Kommandozeile kann der Port mit
--port=8000
angegeben werden.Falls
--port
nicht existiert, soll eine Umgebungsvariableport
ausgewertet werden, die auch auf der Kommandozeile mit-Dport=8020
gesetzt werden kann.Falls die Umgebungsvariable nicht existiert, soll in einer Datei application.properties eine Zuweisung wie
port=8888
ausgewertet werden.Falls überhaupt keine Angabe gemacht wurde, ist der Port standardmäßig mit 8080 belegt.
Zum Schluss soll der Port ausgegeben werden.
Beispiel für drei Aufrufvarianten:
$ java com.tutego.exercise.os.PortConfiguration $ java com.tutego.exercise.os.PortConfiguration --port=8000 $ java -Dport=8020 com.tutego.exercise.os.PortConfiguration
1.3. Externe Prozesse ausführen
Als plattformunabhängige Programmiersprache kann Java nicht alles bieten, und so gibt es verschiedene Möglichkeiten, Anfragen an die Host-Umgebung, an das Betriebssystem, zu stellen. Eine einfache Möglichkeit ist das Aufrufen externer Programme, das in der nächsten Aufgabe gefragt ist.
1.3.1. Über Windows Management Instrumentation den Batteriestatus auslesen ⭐⭐
Bonny Brain spielt auf Ihrem Notebook ein Strategiespiel. Die nächste Runde dauert 30 Minuten, und da Ihr Notebook nur über die Batterie läuft, möchte sie nicht das Spiel abbrechen müssen, wenn die Batterie bald leer ist. Mit folgenden Aufrufen lassen sich unter Windows auf der Kommandozeile die prozentuale verbleibende Laufzeit und die verbleibende Anzahl Minuten geschätzt nach der der aktuellen Last ermitteln:
> wmic path win32_battery get EstimatedChargeRemaining EstimatedChargeRemaining 10 > wmic path win32_battery get EstimatedRunTime EstimatedRunTime 37
Ist der Computer kein Laptop mit Batterie ist die Ausgabe »Keine Instanzen verfügbar.« Wenn der Laptop geladen wird, ist das Ergebnis bei EstimatedRunTime
71582788 (hexadezimal 4444444). Details dazu gibt Microsoft unter https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/win32-battery.
Aufgabe:
Starte in einem Java-Programm über den
ProcessBuilder
das Windows-Programmwmic
als externen Prozess, und lese das Ergebnis vonEstimatedChargeRemaining
undEstimatedRunTime
aus.Berücksichtige im Programm und in der Ausgabe, dass ein Laptop am Stromnetz betrieben werden kann oder ein Desktop-Computer keine Batterie besitzt.
Das Betriebssystem von Microsoft bietet eine API mit dem Namen Windows Management Instrumentation (WMI), mit der Einstellungen eines Computers ausgelesen und zum Teil verändert werden können. WMI ist vergleichbar mit JMX auf der Java-Seite. Weil oft Shellskripte zwecks Automatisierung auf diese Belegung zugreifen möchten, hat Microsoft eine Kommandozeilenschnittstelle Windows Management Instrumentation Command-line (WMIC) geschaffen. Ein WMI-Provider liefert Informationen über CPU-Auslastung, Motherboard, Netzwerk, Batteriestatus und vieles mehr. Folgender Aufruf gibt eine kleine Übersicht: > wmic /? |
Noch mehr Aufgaben findest du im Buch: ›Captain CiaoCiao erobert Java: Das Trainingsbuch für besseres Java. 300 Java-Workshops, Aufgaben und Übungen mit kommentierten Lösungen‹