Angewandte Netzwerktechnik kompakt

Material zum Buch

zu Kapitel 2.2 (Studentenverwaltung)


Für Kapitel 2.2 stehen uns das Interface LesenSchreiben, sowie die Klassen TextIO, BinaerIO, Leistung, Student, Util und Verwaltung zur Verfügung, mit denen zufällig erzeugte Stundentendaten in eine Textdatei (über die Klasse TextIO) oder eine Binärdatei (über die Klasse BinaerIO) geschrieben werden können.

Dazu werden in der Klasse Util Instanzen der Klasse Student und je ein dazugehöriges Array von Instanzen der Klasse Leistung mit zufällig ausgewählten Daten erzeugt und eine Dateihandlerinstanz der für das entsprechende Ausgabeformat benötigten Klasse erstellt. Anschließend werden die Daten in einen OutputStreamWriter (bei einer Textdatei) bzw. einen DataOutputStream (bei einer Binärdatei), jeweils gekoppelt mit einem FileOutputStream, geschrieben.

Im Anschluss wird die erstellt Datei wieder eingelesen und mit den ursprünglichen Daten verglichen, um Fehler beim Schreibvorgang auszuschließen.

Das entsprechende Ausgabeformat kann in der Klasse Verwaltung gewählt werden. Dem hier verlinkten Archiv liegt bereits zu beiden Formaten je eine erzuegte Datei bei.

Am Ende dieser Seite finden Sie eine Vorschau der Java-Klassen.

zu den Übungsaufgaben


Die UTF8-Demo-Datei enthält beispielhaft ausgewählte Zeichen in UTF-8-Codierung. Die Datei muss in einem UTF-8-fähigen Editor geöffnet werden, damit sie korrekt dargestellt werden kann.

Die Binärdatei enthält die Studentendaten aus Kapitel 2.2 im Binärformat.

Vorschau der Java-Klassen zu Kapitel 2.2


Verwaltung.java

import java.io.IOException;

public class Verwaltung {
	public static void main(String[] args) throws IOException, InterruptedException {
		Student[] studenten;
		
		// Datensaetze erzeugen
		studenten = Util.fuelleMitUnsinn(100);
		System.out.println("Array erzeugt");
			
		// Dateihandlerinstanz erzeugen
		LesenSchreiben leseSchreibe = new  
				BinaerIO("BinaerDatei");
		//		TextIO("Textdatei");
		
		// Datei schreiben
		leseSchreibe.schreibeDatei(studenten);
		System.out.println("Array geschrieben");
		
		// Kurze Wartezeit, simuliert Verarbeitung
		Thread.sleep(1000);
		
		// Datei lesen
		Student[] zurueckGelesen = leseSchreibe.leseDatei();
		System.out.println("Array gelesen");
		
		// Vergleichen
		if(Util.sindArraysGleich(studenten, zurueckGelesen))
			System.out.println("Arrays sind gleich");
		else
			System.out.println("Arrays sind ungleich");
	}
}

Leistung.java

public class Leistung {
	String modul;
	double note;
}

//
// 4711 - Hans Muster
// Leistungen - REN 1,0
// 		      - GdaT 5,0
// 4712 - Erika Muster
// Leistungen - keine also Wert == null

Student.java

public class Student {
	int matrikelNummer;
	String name;
	Leistung[] leistungen;
}

LesenSchreiben.java

import java.io.IOException;

// Interface, das das Lesen und Schreiben der Datensaetze kapselt
// Dateinamen/Netzwerkadressen werden in Konstruktur der Klasse behandelt, 
// die instantiiert wird. 
public interface LesenSchreiben {
	void schreibeDatei(Student[] studenten) throws IOException;
    Student [] leseDatei() 	throws IOException;
}

BinaerIO.java

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class BinaerIO implements LesenSchreiben {

	String dateiName;
	
	BinaerIO(String dateiName)
	{
		this.dateiName = dateiName;
	}
	
	@Override
	public void schreibeDatei(Student[] studenten) throws IOException {
		FileOutputStream fos = new FileOutputStream(dateiName);
		DataOutputStream dos = new DataOutputStream(fos);
		
		if(studenten != null) {
			dos.writeInt(studenten.length);
			for(int i=0; i < studenten.length; i++) {
				dos.writeInt(studenten[i].matrikelNummer);
				dos.writeUTF(studenten[i].name);
				if(studenten[i].leistungen != null) {
					dos.writeInt(studenten[i].leistungen.length);

					for(int j=0; j < studenten[i].leistungen.length; j++) {
						dos.writeUTF(studenten[i].leistungen[j].modul);
						dos.writeDouble(studenten[i].leistungen[j].note);
					}
				}
				else
					dos.writeInt(0);	
			}
		}
		else
			dos.writeInt(0);
		dos.close();
		fos.close();
	}

	@Override
	public Student[] leseDatei() throws IOException {
		Student[] geleseneStudenten;

		FileInputStream fis = new FileInputStream(dateiName);
		DataInputStream dis = new DataInputStream(fis);

		int studCnt = dis.readInt();
		if(studCnt != 0)
		{
			geleseneStudenten = new Student[studCnt];
			for(int i=0; i < studCnt; i++) {
				geleseneStudenten[i] = new Student();
				geleseneStudenten[i].matrikelNummer = dis.readInt();
				geleseneStudenten[i].name = dis.readUTF();
				int leistCnt = dis.readInt();

				if(leistCnt != 0) {
					geleseneStudenten[i].leistungen = new Leistung[leistCnt];
					for(int j=0; j < leistCnt; j++) {
						geleseneStudenten[i].leistungen[j] = new Leistung();
						geleseneStudenten[i].leistungen[j].modul = dis.readUTF();
						geleseneStudenten[i].leistungen[j].note = dis.readDouble();
					}
				}
				else
					geleseneStudenten[i].leistungen = null;	
			}

		}
		else
			geleseneStudenten = null;

		dis.close();
		fis.close();
		return geleseneStudenten;
	}
	

}

TextIO.java

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Scanner;

public class TextIO implements LesenSchreiben {

	String dateiName;
	
	TextIO(String dateiName)
	{
		this.dateiName = dateiName;
	}
	
	@Override
	public void schreibeDatei(Student[] studenten) throws IOException {
		FileOutputStream fos = new FileOutputStream(dateiName);
		OutputStreamWriter osw = new OutputStreamWriter(fos,"UTF8");	
		
		// string.format()
		String toWrite;
		
		if(studenten != null) {
			// zu schreibenden Text aus einzelnen Elementen zusammensetzen
			toWrite = String.format("%d",studenten.length );
			// Elemente mit ; und Leerzeichen trennen
			toWrite += "; ";
			// Text als Zeile schreiben
			toWrite += "\n";
			osw.write(toWrite);
	
			for(int i=0; i < studenten.length; i++) {
				// neuen Text beginnen
				toWrite = String.format("%d; %s; ",
						studenten[i].matrikelNummer,
						studenten[i].name);
				if(studenten[i].leistungen != null) {
					// Text ergaenzen
					toWrite += String.format("%d; ",studenten[i].leistungen.length);

					for(int j=0; j < studenten[i].leistungen.length; j++) {
						toWrite += String.format("%s; %3.1f; ",
								studenten[i].leistungen[j].modul,
								studenten[i].leistungen[j].note);
					}
				}
				else
					toWrite += "0; ";
				// Text / Datensatz eines Studenten als Zeile ausgeben
				toWrite += "\n";
				osw.write(toWrite);
			}
		}
		else
		{
			toWrite = "0; \n";
			osw.write(toWrite);
		}
		osw.close();
		fos.close();
	}

	@Override
	public Student[] leseDatei() throws IOException {
		Student[] geleseneStudenten;

		FileInputStream fis = new FileInputStream(dateiName);
		
		// Einen Scanner erzeugen, der den Stream von Trennzeichen zu Trennzeichen liest
			Scanner scan = new Scanner(fis,"UTF8");
			// ; mit oder ohne folgenden Whitespace (Leerzeichen, Tabulator, Zeilenvorschub)
			// als Trennzeichen festlegen
			scan.useDelimiter(";\\s*");
		
		int studCnt = scan.nextInt();
		if(studCnt != 0)
		{
			geleseneStudenten = new Student[studCnt];
			for(int i=0; i < studCnt; i++) {
				geleseneStudenten[i] = new Student();
				geleseneStudenten[i].matrikelNummer = scan.nextInt();
				geleseneStudenten[i].name = scan.next();
				int leistCnt = scan.nextInt();
				if(leistCnt != 0) {
					geleseneStudenten[i].leistungen = new Leistung[leistCnt];
					for(int j=0; j < leistCnt; j++) {
						geleseneStudenten[i].leistungen[j] = new Leistung();
						geleseneStudenten[i].leistungen[j].modul = scan.next(); 
						geleseneStudenten[i].leistungen[j].note = scan.nextDouble();
					}
				}
				else
					geleseneStudenten[i].leistungen = null;	
			}

		}
		else
			geleseneStudenten = null;

		scan.close();
		fis.close();
		return geleseneStudenten;
	}
	
}

Util.java

public class Util {
	static final String [] vornamen = { "Mia","Ben","Emma","Jonas","Hannah","Leon","Sofia","Finn","Anna","Elias"};
	static final String [] nachnamen = {"Bauer","Becker","Fischer","Fuchs","Hartmann","Lang", "Jung","Hofmann","Huber"};
	static final String [] module = {"Analysis A","Lineare Algebra A","Analysis B","Lineare Algebra B","Numerik A",
    "Stochastik A","Stochastik B","Numerik partieller Differentialgleichungen 1","Numerik partieller Differentialgleichungen 2",
    "Baumechanik I (Statik starrer Koerper)","Baumechanik II (Elastomechanik)","Baumechanik III (Kinematik und Kinetik)",
    "Kontinuumsmechanik I","Modellbildung im Ingenieurwesen","Numerische Mechanik","Festkoerpermechanik","Finite Elemente II",
    "Grundlagen der Elektrotechnik","Umweltbiologie und -chemie","Stroemungsmechanik","Thermodynamik im Ueberblick",
    "Datenstrukturen, Algorithmen und Programmierung","Datenbanksysteme im Ingenieurwesen","Graphen und Netze","Baustoffkunde I",
    "Baustoffkunde II","Ausgleichungsrechnung und Statistik I","Ausgleichungsrechnung und Statistik II",
    "Projekte des Ingenieurwesens" };
	
	public static Student[] fuelleMitUnsinn(int Zahl)
	{
		Student[] unsinn = new Student[Zahl];
		
		for(int i=0; i < Zahl; i++) {
			unsinn[i]=new Student();
			int vn_indx = (int)(Math.random()*vornamen.length);
			int nn_indx = (int)(Math.random()*nachnamen.length);
			unsinn[i].name = vornamen[vn_indx] + " " + nachnamen[nn_indx];
			unsinn[i].matrikelNummer = vn_indx * 100 + nn_indx;
			int notenZahl = (int)(Math.random()*8);
			if(notenZahl >= 1) {
				unsinn[i].leistungen = new Leistung[notenZahl];
				for(int j=0; j < notenZahl; j++) {
					int mod_indx = (int)(Math.random()*module.length);
					unsinn[i].leistungen[j] = new Leistung();
					unsinn[i].leistungen[j].modul = module[mod_indx];
					unsinn[i].leistungen[j].note = (int)(Math.random()*5) + 1;
				}
			}
			else
				unsinn[i].leistungen = null;
		}
		return unsinn;
	}
	
	public static boolean sindArraysGleich(Student[] a, Student[] b) {
		boolean istUnGleich = false;
		if(a.length == b.length)
		{
			for(int i=0; i < a.length; i++) {
				istUnGleich |= a[i].matrikelNummer != b[i].matrikelNummer;
				istUnGleich |= !(a[i].name.equals(b[i].name));
				if(a[i].leistungen != null) {
					for(int j=0; j < a[i].leistungen.length; j++) {
						istUnGleich |= !(a[i].leistungen[j].modul.equals(b[i].leistungen[j].modul)) ;
						istUnGleich |= a[i].leistungen[j].note != b[i].leistungen[j].note ;
					}
				}
				if(istUnGleich)
					System.out.println("Ungleich "+i);
			}
		}
		else
			istUnGleich = true;

		return !istUnGleich;
	}
}