Prof. Dr. Th. Letschert FB MNI TH Mittelhessen StudiumPlus Informatik II Aufgabenblatt 6 Gruppenübung Aufgabe 1 CSV Dateien sind Textdateien die Zeilen mit Komma-separierten Werten bestehen (CSV = Comma Separated Values). CSV-Dateien werden sehr häufig zum Datenaustausch zwischen unterschiedlichen Programmen eingesetzt. Statt des Kommas als Trennzeichen, werden oft auch andere Zeichen verwendet. Im deutschsprachigen Raum ist es in der Regel das Semikolon. Ein typischer Einsatz für CSV-Tabellen ist der Import in und der Export aus Tabellenkalkulationsprogrammen wie MS Excel oder Open Office Calc. Angenommen wir haben eine Tabelle mit den Daten: Personalnummer Name Vorname Gehalt 6666 Maulwurf Hans 5000 1234 Dr Hibbert Julius M. 30000 7777 Burns Charles Montgomery 150000000 Bei einem Export ins CSV Format könnte dann eine Datei mit folgendem Inhalt generiert werden: 6666;Maulwurf;Hans;5000 1234;Dr Hibbert;Julius M.;30000 7777;Burns;Charles Montgomery;150000000 Lesen Sie zu CSV den Artikel den Wikipedia-Artikel http://de.wikipedia.org/wiki/csv (Dateiformat) und erstellen Sie dann eine CSV Datei mit dem angegebenen Inhalt (oder einem anderen). Verwenden Sie dazu ein Tabellenkalkulationsprogramm ihrer Wahl oder (im Notfall!) einen Texteditor. Aufgabe 2 Der Inhalt einer Datei wird traditionell an der Dateiendung erkannt, also an dem letzten Bestandteil des Dateinamens. Eine CSV Datei ist danach eine Textdatei mit der Endung.csv. Seit Windows aber wahrscheinlich zu Recht meint, dass der typische Benutzer das Konzept einer Dateiendung nicht versteht und darum Unsinn damit treibt, werden Dateiendungen oft versteckt und können nicht mehr unbedingt zum Erkennen eines Dateityps verwendet werden. Statt den Inhalt einer Datei nur an der Dateiendung kenntlich zu machen beginnt man mit Inhaltstypen (auch MIME Types) zu arbeiten. Einem Konzept, das ursprünglich für die Kennzeichnung von übertragen Daten entwickelt wurde, aber auch für gespeicherte Daten eingesetzt werden kann. Um Nachrichten verschicken zu können, die neben reinem Text auch Bilder, Musik, etc. enthalten können, hat sich die Internet Gemeinde zu Beginn der 90 er Jahre einen Standard ausgedacht, der Bit Ströme als Bestandteile von E Mails eindeutig charakterisiert: den sogenannten MIME Standard. 1 MIME stand dabei ursprünglich für Multipurpose Internet Mail Extension. Der MIME Standard wurde danach in die Web Technologie übernommen und ist heute von großer Bedeutung über das Internet hinaus für jeden Transfer von Daten auch mit Hilfe von Dateien. Man spricht vom MIME Typ oder MIME type manchmal auch vom Internet Media Type. 1. Lesen Sie den Wikipedia Artikel zu MIME Typen http://de.wikipedia.org/wiki/internet Media Type. 1 Zur ersten Multimedia Mail und der Geburt von MIME siehe http://guppylake.com/ nsb/mime.html.
2. Sehen Sie sich auch mal die englischsprachige Variante der Seite an. 3. Finden Sie heraus welcher MIME Typ einer CSV Datei laut Standard zugeordnet sein sollte. Aufgabe 3 Dateien mit einer bestimmten Endung oder einem bestimmten Datei Typ (MIME Typ) können in Java ausfindig gemacht werden. Betrachten Sie folgende Beispiele (Achtung es wird Java 7 vorausgesetzt!): Variante mit Überprüfung der Endung: import java.io.file; import javax.swing.jfilechooser; import javax.swing.joptionpane; public class Test { /** * Lokalisiert Datei mit einem der vorgebenen Dateierweiterungen. * @param msg Text fuer die Dateiauswahl * @param extensions Liste von Erweiterungen, von denen eine der Datei zugeornet sein muss * @return Pfad der ausgwaehlten Datei * @throws IOException */ private static Path locatefilewithextension(string msg, String... extensions) Path p = null; p = f.topath(); if (Files.isRegularFile(p) && Files.isReadable(p) ) { for (String ext: extensions) { if (p.tostring().endswith(ext)) { return p; else break; public static void main(string[] args) Path path = locatefilewithextension("csv Datei", ".csv"); "Sie haben gewaehlt:" + path); Variante mit Überprüfung des Typs: import java.io.file; 2
import javax.swing.jfilechooser; import javax.swing.joptionpane; public class Test { /** * Lokalisiert Datei mit einem der vorgebenen MIME-Typen. * @param msg Text fuer die Dateiauswahl * @param contenttypes Liste von Typen, von denen einer der Datei zugeornet sein muss * @return Pfad der ausgwaehlten Datei * @throws IOException */ private static Path locatefilewithtype(string msg, String... contenttypes) Path p = null; p = f.topath(); if (Files.isRegularFile(p) && Files.isReadable(p) ) { for (String type: contenttypes) { if (Files.probeContentType(p).equals(type)) { return p; else break; public static void main(string[] args) Path path = locatefilewithtype("csv Datei", "text/csv", "text/comma-separated-values"); "Sie haben gewaehlt:" + path); Finden Sie heraus welche Variante(n) bei Ihnen eingesetzt werden kann / können um die CSV Datei zu identifizieren. Das Konzept der Inhaltstypen zur Charakterisierung von Dateiinhalten ist neu. Sie müssen damit rechnen, dass nicht alles unbedingt so wie erwartet funktioniert. Eventuell wird auf Ihrem System ein anderer, als der erwartete Inhaltstyp festgestellt, oder das System liefert gar keinen Inhaltstyp (der Inhaltstyp ist null). Experimentieren Sie! Verwenden Sie eventuell Zwischenausgaben. Fassen Sie dann zusammen: welcher Inhaltstyp wird einer exportierten Tabelle zugeordnet, entspricht dies dem Standard und kann dieser mit Files.probeContentType(path) festgestellt werden. Ist auf Ihrem System nicht Java 7 installiert, dann müssen Sie auf die Prüfung von Inhaltstypen aus einem Programm heraus verzichten. Es bleibt nur der Test auf die Dateiendung. Das Beispiel oben muss dann noch für Java 6 angepasst werden, da Java 6 den Typ Path nicht kennt. Etwa wie folgt: private static File locatefilewithextension_6(string msg, String... extensions) 3
for (String ext: extensions) { if (f.getname().endswith(ext)) { return f; else break; Hausaufgaben Aufgabe 4 Eine CSV Datei beschreibt / codiert eine Tabelle bestehend aus Zeilen und Spalten. Jede Zeile repräsentiert eine Datensatz (engl. Record). Jede Spalte definiert einen Wert in diesen Datensätzen. Die erste Zeile wird oft als Überschriften-Zeile genutzt: Sie enthält dann die Namen der unterschiedlichen Werte eines Datensatzes. Diese Namen nennt man auch Attribute oder genauer Attributnamen. Eine CSV Datei stellt dann eine Liste von Datensätzen dar, in dem jeweils einem Attributnamen ein Attributwert zugeordnet wird. Diese Struktur kann in eine entsprechende Datenstruktur von Java eingelesen werden: import java.io.file; import java.util.list; import java.util.map; import javax.swing.jfilechooser; import javax.swing.joptionpane; public class UserInterface { /** * Lokalisiert Datei mit einem der vorgebenen MIME-Typen. * @param msg Text fuer die Dateiauswahl * @param contenttypes Liste von Typen, von denen einer der Datei zugeornet sein muss * @return Pfad der ausgwaehlten Datei * @throws IOException */ private static Path locatefilewithtype(string msg, String... contenttypes) //... WIE OBEN BZW SO DASSS BEI IHNEN FUNKTIONIERT... public static void main(string[] args) // SO ODER MIT PASSENDEN ANDEREN PARAMETERN! Path path = locatefilewithtype("csv Datei", "text/csv", "text/comma-separated-values"); System.out.println("Die Datei " + path + "Enthaelt die Datensaetze:"); List<Map<String, String>> records = CSV.readCSVFile(path, ";"); for (Map<String, String> m : records) { System.out.println(m); 4
Mit einer Routine zur Analyse von CSV Dateien: import java.nio.charset.charset; import java.util.arraylist; import java.util.hashmap; import java.util.list; import java.util.map; public class CSV { public static List<Map<String, String>> readcsvfile(path path, String seperator) // erste Zeile / Attribute String[] attributes = null; // Ergebnis: alle Zeilen ausser der ersten List<Map<String, String>> res = new ArrayList<Map<String, String>>(); boolean firstline = true; // erste Zeile enthaelt Spalten- (=Attribut-) Namen for (String line : Files.readAllLines(path, Charset.defaultCharset())){ if (firstline) { attributes = line.split(seperator); firstline = false; continue; Map<String,String> entry = new HashMap<>(); String[] values = line.split(seperator); int i = 0; for(string a: attributes) { String value = values[i].trim(); entry.put(a, value); i++; if (i == attributes.length i == values.length) break; res.add(entry); return res; Java 6 Benutzer verwenden beispielsweise den Scanner zum Einlesen: private static File locatecsvfile_6(string msg) if (f.getname().endswith(".csv")) { return f; else break; private static List<Map<String, String>> readcsvfile_6(file file, String seperator) // erste Zeile / Attribute String[] attributes = null; 5
// alle Zeilen ausser der ersten List<Map<String, String>> res = new ArrayList<Map<String, String>>(); boolean firstline = true; // erste Zeile enthaelt Spalten- (=Attribut-) Namen Scanner scan = new Scanner(file); while (scan.hasnextline()){ String line = scan.nextline(); if (firstline) { attributes = line.split(seperator); firstline = false; continue; Map<String,String> entry = new HashMap<>(); String[] values = line.split(seperator); int i = 0; for(string a: attributes) { String value = values[i].trim(); entry.put(a, value); i++; if (i == attributes.length i == values.length) break; res.add(entry); scan.close(); return res; Testen Sie das Programm mit Ihrer CSV Datei. Verwenden Sie den für Ihr System geeigneten Mechanismus zur Identifikation der CSV Datei. Erstellen Sie eine Liste aller String Operationen und aller Datei Operationen die in der Klasse CSV verwendet werden und informieren Sie sich über deren Wirkung. (API Doku!) Aufgabe 5 Definieren Sie Klasse Person und erweitern Sie UserInterface derart, dass die aus der Datei eingelesen Informationen in eine Liste von Personen Objekten gespeichert wird. Die Klasse der Personen soll dabei die zu den Attributen eines Datensatzes passenden Objektvariablen haben: personalnummer, name, vorname, gehalt. 6