Mittwoch, 23. März 2011
Literaturverwaltung - RandomAccessFile (POS1: 2A, 2C)
Jemand will Zeitschriftenartikel, Bücher und Internet-Links für seine Recherchen verwalten. Schreiben Sie dazu eine Java-Klasse (plus eventuelle Hilfsklassen), welche es ermöglicht diese Daten in einer RandomAccess-Datei zu speichern. Folgende Daten sollen in der Klasse
Eintrag
erfasst werden:- autor -
String(100)
- titel -
String(100)
- erscheinungsjahr -
int
- verlag -
String(30)
- zeitschrift -
String(30)
- seiten -
String(10)
- link -
String(60)
String(100)
bedeutet, dass dafür maximal 100 (genau 100) Zeichen gespeichert werden soll. Sie können das so implementieren, dass kürzere Strings hinten mit Leerzeichen gefüllt werden. Längere Strings müssen abgeschnitten werden. Für eine eventuelle Anzeige/Ausgabe müssen aber die Füllzeichen entfernt werden. Die Klasse Eintrag
ist mit entsprechenden Getter- und Setter-Methoden auszustatten (die bei den Strings das Abschneiden und Auffüllen bewerkstelligen).Die Klasse
Literatur
für die Verwaltung der Datensätze soll folgende Methoden bereitstellen:public void neuerEintrag(Eintrag eintrag)
- fügt einen neuen Eintrag in die Datei ein.public Eintrag lese(int nummer)
- liefert den Eintrag an der Stellenummer
odernull
, falls dieser Eintrag nicht existiert.public void loescheEintrag(int nummer)
- löscht den Eintrag an der Stellenummer
(tut nichts, wenn es den Eintrag nicht gibt).
Der Konstruktor der Klasse Literatur soll eine geöffnete RandomAccess-Datei als Parameter haben:
public Literatur(RandomAccessFile file)
Implementieren Sie das Löschen so, dass der jeweilige Eintrag als gelöscht markiert wird (zusätzliches Feld) und diese Änderung in der Datei gespeichert wird. Der Datensatz ist also physisch noch in der Datei. Bei der Methode
lese()
muss also im Falle eines gelöschten Eintrags null
geliefert werden.Umgekehrt muss bei
neuerEintrag()
zunächst ein gelöschter Eintrag gesucht werden. Wird ein solcher gefunden, so wird er durch den neuen ersetzt (Lösch-Markierung muss wieder zurückgesetzt werden). Wird kein gelöschter Datensatz gefunden, so ist der neue an die Datei anzuhängen.Schreiben Sie ein kleines Testprogramm zum Testen Ihrer Klassen.
Anmerkung: Die Daten sind für eine echte Anwendung nicht ausreichend und müssten unterteilt werden, da es z.B. mehrere Autoren für einen Artikel gibt.
Hinweis: hier finden Sie eine Testklasse zum Testen der Klasse
Literatur
. Die Klasse Literatur
muss wie diese Testklasse im Package literatur
sein. Weiters muss die Library für JUnit 3 angegeben werden. Diese Testklasse trifft gewissen Annahmen zur Implementierung von Literatur
und Eintrag
. Bitte passen Sie entweder die Testklasse an Ihre Implementierung an oder Sie ändern Ihre Literatur
bzw. Eintrag
-Klassen entsprechend (z.B. nimmt der Test an, dass es eine read()
und eine write()
-Methode gibt, die einen Datensatz ("in sich hinein") liest bzw. einen Datensatz ("sich selbst") schreibt (jeweils an die Position, die in Literatur
bestimmt wurde).Ihre Klasse Eintrag könnte etwa so beginnen:
public class Eintrag { // Feldlängen private final static int autorLen = 100; private final static int titelLen = 100; private final static int verlagLen = 30; private final static int zeitschriftLen = 30; private final static int seitenLen = 10; private final static int linkLen = 60; // Felder private String autor; private String titel; private int erscheinungsjahr; private String verlag; private String zeitschrift; private String seiten; private String link; // gelöscht? private boolean istGeloescht = false;Da eine fixe Datensatzlänge gefordert ist, müssen Sie die Länge ermitteln, indem Sie die Längen der einzelnen Felder zusammenzählen. Wir schätzen für
Boolean
die Länge von int
(bestimmt mit Hilfe der Wrapperklasse Integer
und der Konstante SIZE
, welche die Länge in Bits angibt).public static int eintragLen() { int len = Integer.SIZE / 8 + (autorLen + titelLen + verlagLen + zeitschriftLen + seitenLen + linkLen) * 3 + 6 * Long.SIZE / 8 + Integer.SIZE / 8; return len; }Der Faktor 3 entsteht durch die Verwendung der UTF-8-Kodierung. UTF-8 ist eine Kodierung des Unicodes und speichert alle Zeichen des ASCII-Codes auch in der selben Kodierung wie ASCII, daher werden dann für andere Zeichen 2, 3 bzw. 4 Bytes verwendet (Unicode verwendete in den ersteren Versionen 16 Bit, in Java werden daher Zeichen mit 16 Bit kodiert). Um ganz sicher zu sein, müsste man den Faktor 4 verwenden.
Long.SIZE / 8
ist die Längeninformation, die in jedem String-Objekt gespeichert ist.Strings werden mit
file.writeUTF(string);
geschrieben bzw. mit string = file.readUTF();
gelesen.public void write(RandomAccessFile out) throws IOException { out.writeBoolean(istGeloescht); out.writeUTF(autor); out.writeUTF(link); out.writeUTF(seiten); out.writeUTF(titel); out.writeUTF(verlag); out.writeUTF(zeitschrift); out.writeInt(erscheinungsjahr); } public void read(RandomAccessFile in) throws IOException, EOFException { istGeloescht = in.readBoolean(); autor = in.readUTF(); link = in.readUTF(); seiten = in.readUTF(); titel = in.readUTF(); verlag = in.readUTF(); zeitschrift = in.readUTF(); erscheinungsjahr = in.readInt(); }
Die String-Felder müssen natürlich auf eine fixe Länge gebracht werden, d.h. zu lange Strings müssen abgeschnitten, zu kurze evtl. verlängert werden. Dies erledigt man am Besten in den Setter- bzw. Getter-Methoden.
Das Lesen eines Datensatzes in der Klasse
Das Lesen eines Datensatzes in der Klasse
Literatur
könnte etwa so funktionieren:public Eintrag lese(int nummer) throws IOException { long pos = nummer * Eintrag.eintragLen(); if (pos < file.length()) { file.seek(pos); Eintrag eintrag = new Eintrag(); eintrag.read(file); if (!eintrag.istGeloescht()) { return eintrag; } else { return null; // gelöschter Eintrag gilt als nicht vorhanden } } else { return null; // über die Dateilänge hinaus } }Vervollständigen Sie mit diesen Informationen Ihre Klassen.
Nennen Sie das Projekt
klasse-name-literatur
(klasse
... 2a, 2b, 2c, name
... Ihr Familienname), z.B. 2a-haberstroh-literatur
.Abonnieren Posts [Atom]
Kommentar veröffentlichen