Klasse mit "gezipten" Daten

Hallo,

derzeit verwende ich für ein Programm eine Textdatei mit 50.000 Zeilen, jede mit 83 Zeichen, als Basis für eine bestimmte Ausgabe. Wird auf eine dieser Zeilen zugegriffen, wird damit auch deren Inhalt verändert. Beim beenden des Programms wird die veränderte Textdatei gespeichert.

Die erwähnte Textdatei ist allerdings gezipt und wird beim Beenden des Programms wieder als ZIP-Datei gespeichert. Das funktioniert alles einwandfrei. Trotzdem hätte ich es gerne, wenn die externe ZIP-Datei nicht benötigt würde und die Daten stattdessen intern, also in der JAR-Datei, bereitgestellt würden. Ideal wäre es, wenn ich dafür weitgehend auf den bisher verwendeten Code zurückgreifen könnte.

Hier der aktuelle Konstruktor, über den die gezipte Datei geöffnet wird:
Java:
    /**
     * Konstruktor
     * @param mfrm Referenz zur aufrufenden Klasse
     * @param pfad Pfad für das Archiv
     */
    public Archiv(Str8tsApp mfrm, String pfad) {
        strApp = mfrm;    
        userDir = pfad;
        ZipFile zipFile = null;
        try {
            zipFile = new ZipFile(userDir + "\\arche.kar");
        } catch (IOException ex) {
            System.err.println("Fehler beim Öffnen der ZIP-Datei");
            error = 1;
            errorTxt = "die Datei arche.kar konnte nicht gefunden werden";
        }
        if (zipFile != null) {
            Enumeration enu = zipFile.entries();
            ZipEntry zipEntry = (ZipEntry) enu.nextElement();
            zipName = zipEntry.getName();
            BufferedInputStream bis = null;
            byte[] buffer = null;
            try {
                bis = new BufferedInputStream(zipFile.getInputStream(zipEntry));
                int avail = bis.available() + 20;    // +20 falls am Ende kein LF
                nAufgaben = avail / ZLAENGE;
                aufgaben = new Aufgabe[nAufgaben];
                if (avail > 0) {
                    buffer = new byte[avail];
                    bis.read(buffer, 0, avail);
                }
            } catch (IOException ex) {
                System.err.println("Fehler beim Einlesen der ZIP-Datei");
                error = 2;
                errorTxt = "Fehler beim Einlesen der ZIP-Datei";
            } finally {
                try {
                    if (bis != null) {
                        bis.close();
                    }
                } catch (Exception ex) {
                    System.err.println("Fehler beim Schließen der ZIP-Datei");
                    error = 3;
                    errorTxt = "Fehler beim Schließen der ZIP-Datei";
               }
            }
            byte[] tmp = new byte[81];
            int bi = 0;
            for (int i = 1; i < 6; i++) {
                lpos[i] = new Bereich();
            }
            lpos[1].start = 0;
            lpos[5].ende = nAufgaben-1;
            int level = 1;
            for (int i = 0; i < nAufgaben; i++) {
                aufgaben[i] = new Aufgabe();
                aufgaben[i].level = buffer[bi++] - 48;
                if (aufgaben[i].level > level) {
                    lpos[level].ende = i-1;
                    lpos[++level].start = i;
                }
                aufgaben[i].status = buffer[bi++] - 48;
                System.arraycopy(buffer, bi, tmp, 0, 81);
                aufgaben[i].aufgabe = new String(tmp);
                bi += 83;
            }
        }
    }
Und hier der Code, welcher bei Programmende die Daten wieder gezipt zurückschreibt:
Java:
    /**
     * Speichert das Archiv als gezipte Datei.
     * @param buffer
     */
    private void saveZip(byte[] buffer) {
        ZipOutputStream zipOut = null;
        try {
            zipOut = new ZipOutputStream(
                    new FileOutputStream(userDir + "\\arche.kar"));
            ZipEntry ze = new ZipEntry(zipName);
            zipOut.putNextEntry(ze);
            zipOut.write(buffer, 0, buffer.length);
            zipOut.closeEntry();
        } catch (IOException ex) {
            System.err.println("Fehler beim Schreiben der ZIP-Datei");
        } finally {
            try {
                if (zipOut != null) {
                    zipOut.close();
                }
            } catch (Exception ex) {
                System.err.println("Fehler beim Schließen der ZIP-Datei");
            }
        }
    }
Es wäre schön, wenn jemand eine Idee hätte, wie man das durch eine interne Speicherung, wegen des Datenumfanges möglichst auch gezipt, realisieren könnte. Übrigens, von all den Fehlermeldungen, die hier im Code vorgesehen sind, kam bisher keine zum Einsatz. Es funktioniert bestens.

kodela
 
Zuletzt bearbeitet:
Ein Jar ist ein Zip. Da brauchst Du nicht nochmal zippen :) Allerdings: von einem Ändern der Anwendungs-Jar würde ich abraten. Du weißt nie, ob das System den Zugriff darauf nicht sperrt. So würde mich es nicht wundern, wenn das unter bestimmten Systemen, die z. B. mit einem W im Namen beginnen, nicht funktioniert, so lange die Anwendung läuft.
 
Danke mihe7!

Dass ein Jahr ein Zipp ist, ist mir bewusst. Trotzdem habe ich nicht daran gedacht, dass es genau deshalb keinen Sinn machen würde, mit gezipten Daten zu arbeiten. Bleibt die Frage, wie die veränderten (ungezipten) Daten von der JAR-Datei übernommen werden könnten, so dass beim nächsten Start nicht mit die ursprünglich einmal vorhandenen Daten sondern die zwischenzeitlich geänderten Daten verwendet werden können. Die Daten würden sich zwar nicht in ihren Umfang sondern nur inhaltlich ändern. Wo vorher z.B. "12345" stand, müsste das Programm beim nächsten Aufruf "23456" vorfinden. Ist so etwas möglich? Wenn ja, wie?

Deine Bedenken bezüglich einer Änderung der Anwendungs-JAR beziehen sich, wenn ich Dich richtig verstehe, auf die Zeit, während die Anwendung läuft. Man könnte aber eventuell, so wie ich es auch jetzt mache, alle 50.000 Datensätze übernehmen, bei Bedarf einzelne Datensätze ändern und bei Programmende alle Daten wieder zurück schreiben. Das ist sicher sehr laienhaft gedacht, aber ein solcher bin ich ja auch.

Der Grund, weshalb ich auf solche "krummen" Gedanken gekommen bin, ist die Unabhängigkeit der JAR-Datei von einer externen Archiv-Datei.
 
Man könnte z. B. in einer Batch-Datei die Aktualisierung nach dem Programmende durchführen, also etwa:
1. Starte Anwendung
2. Nach Anwendungsende aktualisiere das Jar

Für 2. brauchst Du aber ein Programm, z. B. eine Zip-/Jar-/Anwendung oder ein Java-Programm (2. Jar), das den Spaß übernimmt. Du bist also auch hier von mindestens einer externen Datei abhängig - dann kannst Du gleich Deine Daten separat ablegen.
 
Es wäre auch eine sinnvolle Entscheidung eines Systemadministrators, usern kein Recht zu geben, Programme zu ändern. In deinem Fall hätte der user kein Recht, die jar-Datei zu schreiben. Er könnte aber die zip-Datei mit den Daten - die möglicherweise an einer anderen Stelle liegt - schreiben.
 
Danke mihe7, danke fhoffmann,

Eure Argumente sind mehr als nur überzeugend. Also vergesse ich, was ich mir da ausgemalt hatte.

kodela
 
Passende Stellenanzeigen aus deiner Region:

Neue Themen

Oben