Mittwoch, 2. Juni 2010

 

Literaturverwaltung - RandomAccessFile

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:
  1. autor - String(100)
  2. titel - String(100)
  3. erscheinungsjahr - int
  4. verlag - String(30)
  5. zeitschrift - String(30)
  6. seiten - String(10)
  7. 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:
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.

Hinweishier 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 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-literatur-name (klasse ... 2ad, 2bd, 2cd, name ... Ihr Familienname), z.B. 2ad-literatur-haberstroh.

Labels: , ,


Kommentare:

Kommentar veröffentlichen

Abonnieren Kommentare zum Post [Atom]





<< Startseite

This page is powered by Blogger. Isn't yours?

Abonnieren Posts [Atom]