(Geplante) Änderungen an einer Datei vorübergehend speichern und anwenden?

Jacobdabozze

Mitglied
Guten Tag,


Für meine Belegarbeit arbeite ich momentan an einer Anwendung, die Dateien Byte-weise einliest und ausgibt.
Letztendlich handelt es sich um einen erweiterten File-Viewer mit Bearbeitungs-, und später auch Suchoptionen.

appqskqz.png


Das Problem ist, dass ich aus Ressourcengründen nicht in der Lage bin, Datein komplett einzulesen und diese als Byte-Array zu speichern. Hantiert man mit sehr großen Datenmengen, läuft der Arbeitsspeicher voll.
Um dieses Problem zu lösen, lese ich die Daten immer nur Abschnittsweise ein - in diesem Fall 120 Byte pro Aktion.

Wenn auch die Performance um ein vielfaches gesteigert wird, stehe ich nun vor einem schwierigen Problem:
Wie kann ich geplante Änderungen, wie zum Beispiel das Hinzufügen oder Löschen von Daten umsetzen?

Folgende mögliche Varianten habe ich im Kopf:
- eine vollständige Kopie der Datei (Kopie kann sehr viel Speicher fressen, dazu Kopieraufwand, allerdings am leichtesten zu bearbeiten)
- eine "Schatten"-Datei, in welche nur die Daten bis zum geänderten Index kopiert und geändert werden - bei Änderung vorne in der Originaldatei sehr klein, bei Änderung hinten fast so groß wie das Original (potenziell kleiner, potenziell geringerer Kopieraufwand, etwas schwieriger damit zu arbeiten)
- eine Art Register, das alle Änderungen vermerkt - diese Änderungen werden bei jedem Einlesen der Datenblöcke aus der Original-Datei beachtet, also als eine Art Filter, wird beim Speichern in die Original-Datei ebenfalls beachtet (benötigt wenig Speicher, schwierig zu implementieren, *1)

*1 - kann bei vielen Änderungen die Einlesezeit beeinträchtigen, allerdings bietet sich meine Anwendung nicht dafür an, sehr viele Änderungen vorzunehmen


Welche Idee würdet ihr nutzen, oder kennt ihr vielleicht sogar eine noch bessere Lösung?

Ich bedanke mich für jede Hilfe,
Jacob
 

Robert Zenz

Top Contributor
Tatsaechlich klingt das nach einer guten Anwendung fuer RnadomAccessFile, falls du das noch nicht verwendest.

Und da die Aenderungen, also die Anzahl und Groesze dieser, recht ueberschaubar klingt, wuerde ich zur Dritten Variante tendieren. Also dass du dir alle Aenderungen merkst und diese dann "ueberblendend" zur richtigen Datei anzeigst.

Das ist auch nicht wirklich schwierig zu implementieren. Du musst dir nur das Offset und den neuen Wert merken. Jedes mal wenn du einen Wert anzeigst, kontrollierst du ob fuer diesen Offset ein neuer Wert existiert.
 

Jacobdabozze

Mitglied
Das hängt ein wenig von der Art der Dateien ab. Für den allgemeinen Fall würde ich auch zur letzten Variante tendieren - ein "Redo-Log", das beim Öffnen der Datei angewendet wird.
Kannst Du mir dazu einen guten Artikel empfehlen?

Die Grundidee ist mir durchaus klar, nur bin ich mir unsicher, wie ich es schaffe, dass beim Löschen/ Hinzufügen von Bereichen/ Elementen, und später dem Durchsuchen der Datei ohne Speichern diese Änderungen beachtet werden.

Sich im Log überschneidende Ereignisse müssen/ sollten zudem ebenfallse vorher korrigiert werden.
 

Jacobdabozze

Mitglied
Tatsaechlich klingt das nach einer guten Anwendung fuer RnadomAccessFile, falls du das noch nicht verwendest.

Und da die Aenderungen, also die Anzahl und Groesze dieser, recht ueberschaubar klingt, wuerde ich zur Dritten Variante tendieren. Also dass du dir alle Aenderungen merkst und diese dann "ueberblendend" zur richtigen Datei anzeigst.

Das ist auch nicht wirklich schwierig zu implementieren. Du musst dir nur das Offset und den neuen Wert merken. Jedes mal wenn du einen Wert anzeigst, kontrollierst du ob fuer diesen Offset ein neuer Wert existiert.
Tatsächlich arbeite ich bereits mit RandomAccessFile :D

Leider bin ich mir noch nicht so ganz sicher, wie ich dieses Überblenden angehe.

Bisher habe ich es so gemacht, dass ich ein Byte-Array nutze, welches den entsprechen Abschnitt einliest. Die Länge des Arrays ist dabei von der Anzahl einzulesender Elemente abhängig und wird berechnet:
1) volle Seite -> alle 120 Elemente
2) Seite nicht voll -> 120 Elemente - Anzahl der unbesetzen Elemente

Wenn ich nun allerdings diesen Log führe, dann weiß ich nicht direkt, wie lang das Array werden soll - zumindest sind dann meine vorherigen Rechnungen für die Tonne.

Wie kann man das angehen?
 

Jacobdabozze

Mitglied
Moment, sind das strukturierte Daten, die in Seiten organisiert sind?
Nein, das ist ein Missverständnis- nur zeige ich in meiner grafischen Oberfläche 120 Elemente je Seite an, das ist gemeint.
Wird die Seite gefüllt (das erechne ich aus dem Index und der Länge der Datei), dann werden alle 120 gezeigt, das Array hat eine Länge von 120.
Können keine 120 Elemente ausgelesen werden, dann ist das Array entsprechend kürzer.
 

Robert Zenz

Top Contributor
Also ich wuerde nicht in Seiten arbeiten, sondern in Offsets. In etwas Pseudo-Code:

Java:
public class Change {
    public int offset;
    public byte newValue;
}

public class Diff {
    public SomeMagicClassMaybeMap<Change> changes;
    
    public void addChange(int offset, int newValue) {
        changes.add(new Change(offset, newValue));
    }
    
    public void getChange(int offset) {
        return changes.get(offset);
    }
}

Du kannst dir auch mehrere Bytes je Aenderung merken. Natuerlich musst du dann fuer jedes Byte nachsehen ob es eine Aenderung gibt, aber da du ohnehin nur 120 gleichzeitig anzeigst, ist es komplett vernachlaessigbar.
 

mihe7

Top Contributor
Nein, das ist ein Missverständnis- nur zeige ich in meiner grafischen Oberfläche 120 Elemente je Seite an, das ist gemeint.
Wird die Seite gefüllt (das erechne ich aus dem Index und der Länge der Datei), dann werden alle 120 gezeigt, das Array hat eine Länge von 120.
Können keine 120 Elemente ausgelesen werden, dann ist das Array entsprechend kürzer.
Ok.

Im Prinzip zeichnet das Redo-Log auf, was der Anwender gemacht hat und das wird einfach wieder abgespult. Damit erledigt sich das Problem von Überschneidungen automatisch. Natürlich könnte man hier optimieren und Ereignisse zusammenfassen, aber das wäre etwas für später.

Was direkte Ersetzungen betrifft, wäre die Sache sehr einfach (s. Beispiel von @Robert Zenz), das Problem aber ist, dass Du Bytes entfernen und hinzufügen willst, was sich natürlich auf die Offsets der nachfolgenden Bytes auswirkt.

Daher musst Du das Redo-Log komplett durchgehen und Einträge, die keine wesentlich größeren Offsets betreffen, berücksichtigen. Allerdings wirken sich diese meist nur auf das Offset aus.

Beispiel (mit einem Array): [1,2,3,4,5,6,7,8,9,10], füge ich an Offset 2 [21,22] ein, dann würde sich [1,2,21,22,3,4,5,6,7,8,9,10] ergeben. D. h. das Offset des Eintrags "3" verschiebt sich von 2 nach 4, während das Offset des Eintrags "2" nach wie vor bei 1 bleibt.

Zeige ich jetzt die Bytes ab Offset 8 an, interessieren mich nicht die Werte ([21,22]) der vorherigen Operation, sondern nur, dass sich das Offset um 2 verschoben hat. Dann nämlich muss ich von der gewünschten 8 die 2 abziehen, um aus dem Ur-Array alle Werte ab Offset 6 einzulesen: [7,8,9,10]
 

Jacobdabozze

Mitglied
Ok.

Im Prinzip zeichnet das Redo-Log auf, was der Anwender gemacht hat und das wird einfach wieder abgespult. Damit erledigt sich das Problem von Überschneidungen automatisch. Natürlich könnte man hier optimieren und Ereignisse zusammenfassen, aber das wäre etwas für später.

Was direkte Ersetzungen betrifft, wäre die Sache sehr einfach (s. Beispiel von @Robert Zenz), das Problem aber ist, dass Du Bytes entfernen und hinzufügen willst, was sich natürlich auf die Offsets der nachfolgenden Bytes auswirkt.

Daher musst Du das Redo-Log komplett durchgehen und Einträge, die keine wesentlich größeren Offsets betreffen, berücksichtigen. Allerdings wirken sich diese meist nur auf das Offset aus.

Beispiel (mit einem Array): [1,2,3,4,5,6,7,8,9,10], füge ich an Offset 2 [21,22] ein, dann würde sich [1,2,21,22,3,4,5,6,7,8,9,10] ergeben. D. h. das Offset des Eintrags "3" verschiebt sich von 2 nach 4, während das Offset des Eintrags "2" nach wie vor bei 1 bleibt.

Zeige ich jetzt die Bytes ab Offset 8 an, interessieren mich nicht die Werte ([21,22]) der vorherigen Operation, sondern nur, dass sich das Offset um 2 verschoben hat. Dann nämlich muss ich von der gewünschten 8 die 2 abziehen, um aus dem Ur-Array alle Werte ab Offset 6 einzulesen: [7,8,9,10]
Das ist sehr verständlich.

Eine Frage hätte ich noch, eh ich nun eine wenig sinnvolle Variante eines solchen Logs erstelle:
Wie designed man diesen idealerweise?

Sollte ich den Log in eine temporäre Datei schreiben, oder eine Variante ähnlich der von Robert Zens wählen?
Wie formuliere ich am besten in den Einträgen, dass ein Element gelöscht/ hinzugefügt wurde?

Mir schwirren da einige Ideen durch den Kopf von wegen Befehle wie "Delete" oder ähnliches, die ich beim Einlesen erkenne und anwende.
Doch so wirklich schnell kann das nicht sein.

Leider habe ich damit absolut keine Erfahrungen.

Danke erstmal :D
 

mihe7

Top Contributor
Sollte ich den Log in eine temporäre Datei schreiben, oder eine Variante ähnlich der von Robert Zens wählen?
Natürlich musst Du das Log in eine Datei schreiben, sonst gibt es ja keinen Sinn, das wäre bei @Robert Zenz nicht anders (davon hat er nur abstrahiert). Temporär ist die Datei insofern, als dass sie irgendwann nicht mehr benötigt wird, nämlich wenn die Änderungen endgültig angenommen oder abgelehnt werden.

Doch so wirklich schnell kann das nicht sein.
Nein, schnell ist das nicht, weil Du Speicher sparen willst/musst. Aber ich würde es einfach mal probieren, manchmal ist man positiv überrascht.

Wie formuliere ich am besten in den Einträgen, dass ein Element gelöscht/ hinzugefügt wurde?
In der Log-Datei? Da würde ich z. B. eine Struktur wie

OffsetLängeBedeutung
04Offset
41Art der Änderung (0 = Ersetzung, 1 = Hinzufügen, 2 = Löschen)
51Anzahl der von der Änderung betroffenen Bytes n
6n / 0 bei Löschungneue/geänderte Bytes, nichts bei Löschung

versuchen. Hier würdest Du halt 6 Bytes lesen. Die restlichen n Bytes (über)liest Du dann einfach im Fall der Fälle.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
C .Ini-Datei Wert Änderungen werden nicht angenommen Allgemeine Java-Themen 3
R Änderungen in einem Verzeichnis beobachten - Windows Allgemeine Java-Themen 3
P Variablen in einer anderen Klasse auf Änderungen überwachen Allgemeine Java-Themen 12
martin82 Java Runtime Update >17 - SwingWorker Änderungen? Allgemeine Java-Themen 7
J GUI Änderungen und Threads Allgemeine Java-Themen 11
A java.io-Änderungen zwischen java 1.4 und 1.6 Allgemeine Java-Themen 18
D Änderungen an einer lokalen Datei abprüfen/überwachen Allgemeine Java-Themen 4
N Applet übernimmt keine Änderungen Allgemeine Java-Themen 13
G TreeSet ändert sich bei Änderungen nicht! Allgemeine Java-Themen 15
S Änderungen im Source-Code direkt verwenden können? Allgemeine Java-Themen 3
O Text aus einer Textdatei rausholen, der zwischen zwei Schlüsselworten steht Allgemeine Java-Themen 4
V Umgang mit fehlenden Daten in einer Java-Datenanalyseanwendung Allgemeine Java-Themen 5
M Methodenübersicht einer Klasse einsehen Allgemeine Java-Themen 14
T JNA, Aufruf der Funktionen einer dll Allgemeine Java-Themen 5
I Vom Monolith zu Services in einer Webseite Allgemeine Java-Themen 1
W Variable Initialisierung mit dem Ergebnis einer Regex Allgemeine Java-Themen 1
O Werte einer Generic LinkedList zusammenrechenen Allgemeine Java-Themen 14
C Sortieren und Selektieren einer ArrayList<Point3D> Allgemeine Java-Themen 6
A Einzelne Objekte und Unterobjekte einer ArrayList ausgeben Allgemeine Java-Themen 53
TheSepp Wie kann man Leerzeichen aus einer Array liste entfernen? Allgemeine Java-Themen 10
B Ein Objekt einer Klasse mehreren anderen Klassen zur Verfügung stellen? Allgemeine Java-Themen 6
M Optimierung einer Methode (byte-Geraffel) Allgemeine Java-Themen 2
I Wie kann ich den Wert aus einer If abfrage ausgeben Allgemeine Java-Themen 23
S HTML einer Webseite 1:1 so bekommen wie es auch der Browser anzeigt? Allgemeine Java-Themen 14
melaniemueller Einzelne Zeile aus einer txt Datei in einem String speichern Allgemeine Java-Themen 12
L Java überprüfen lassen, ob sich ein gegebener Pfad / das Programm an sich auf einer CD oder Festplatte befindet Allgemeine Java-Themen 14
ME2002 Fragen aus einer Java Klausur Allgemeine Java-Themen 67
_user_q Obfuscate einer .jar-Datei mit ProGuard? Allgemeine Java-Themen 2
_user_q Verknüpfung einer .jar-Datei (liegt z. B. auf dem Desktop) im Autostart-Ordner erstellen? Allgemeine Java-Themen 20
C Parsen einer sich updatenden Html mithilfe von jsoup Allgemeine Java-Themen 4
E Eine Methode einer extendeten Klasse deakitivieren Allgemeine Java-Themen 12
H Performance einer Monte-Carlo-Simulation verbessern Allgemeine Java-Themen 6
LimDul Kam eine java.net.URL zu einer HashMap und ging als DNS Anfrage wieder heraus Allgemeine Java-Themen 18
E Variablen Nach Übergabe einer Variable den Constructor aufrufen Allgemeine Java-Themen 16
Zeppi NullPointerException in einer if-Abfrage Allgemeine Java-Themen 6
D Abbruch einer ViewScoped Bean in Arbeit Allgemeine Java-Themen 2
Lukas2904 Schleife mit ansteuerung einer Klasse Allgemeine Java-Themen 5
d.lumpi Aus Einer Klasse auf ein Objekt einer anderen Klasse Zugreifen Allgemeine Java-Themen 1
Lukas2904 Wie kann man cps (ClicksPerSecond) in einer GUI anzeigen lassen? Allgemeine Java-Themen 4
O Produziert das Tool "jpackage" (ab JDK 14) .exe Dateien, die auf einer Zielumgebung ohne JRE lauffähig sind ?` Allgemeine Java-Themen 7
R Lambda Expression in einer Methode execute() aufrufen (execute() ist eine Methode aus dem funktionalen Interface Command) Allgemeine Java-Themen 5
Drachenbauer wie kann ich alle instanzen einer Klasse durchsehen, ohne, dass diese in einer Liste erzeugt wurden? Allgemeine Java-Themen 11
N BlueJ Implementation einer Analoguhr Allgemeine Java-Themen 0
O Formatierte String ausgabe bei vier Variablen in einer Zeile Allgemeine Java-Themen 1
N Speicherort einer Datei im Explorer ändern Allgemeine Java-Themen 8
O Datentypen Wie kann ich den Typ einer ArrayList abfragen ? Allgemeine Java-Themen 7
O Leerzeichen und Umlaute im Pfad einer Java Applikation machen Probleme Allgemeine Java-Themen 13
H Mehrere PNG-Files in einer Datei Allgemeine Java-Themen 9
G Java Editor Löschen doppelter Zahlen einer Liste Allgemeine Java-Themen 2
J JSON Daten von einer Webseite erhalten Allgemeine Java-Themen 2
L RegEx für Teile einer Berechnung Allgemeine Java-Themen 14
L Erste Schritte TDD testen einer Methode mit injezierten Services? Allgemeine Java-Themen 12
J Zerlegen einer Zahl Allgemeine Java-Themen 6
Zrebna Wie kann man endgültig aus einer Rekursion ausbrechen? Allgemeine Java-Themen 14
MiMa Person in einer Arraylist hinzugügen mit Prüfung ? Allgemeine Java-Themen 6
Meeresgott Effizientester Weg um nach der Value einer verschachtelten Map aufzulösen Allgemeine Java-Themen 5
H Mehrere Datentypen in einer Arraylist speichern Allgemeine Java-Themen 9
MiMa Prüfziffer einer EAN Nummer berechnen Allgemeine Java-Themen 4
MiMa Erstellungsdatum einer Datei Allgemeine Java-Themen 10
Drachenbauer Wie kann ich einer existierenden Enum von außerhalb veränderte Werte zuweisen? Allgemeine Java-Themen 5
S HTML den ich von einer URL hole nicht identisch mit dem HTML im Browser Allgemeine Java-Themen 1
S Rückgabe einer HttpURLConnection für eine Seite einlesen bei der man eingeloggt ist..? Allgemeine Java-Themen 5
O Java-Applikation tut in Netbeans, als JAR nicht, wegen Pfadangaben einer benötigten Datei Allgemeine Java-Themen 8
M Hilfe bei einer Java Programmieraufgabe! Ab morgen Montag um 08:00 Uhr Allgemeine Java-Themen 5
J Algorithmen Analyse einer Schleife Allgemeine Java-Themen 6
Drachenbauer Wie finde ich den Aufrufer zu einer Methode, die sich nicht in meinem Projekt befindet? Allgemeine Java-Themen 2
J Die Letzte Zahl aus einer Text datei lesen Allgemeine Java-Themen 8
P einen public <Optinal String> in einer anderen Klasse mit einem Int vergleichen Allgemeine Java-Themen 2
A Mithilfe von einer Nummer einen Namen finden n-Beziehung Allgemeine Java-Themen 8
Scream_ilias Auf einer Website die anmeldedaten eingeben Allgemeine Java-Themen 9
V Threads Probleme beim Aufrufen von Methoden einer anderen Klasse (Threads) Allgemeine Java-Themen 14
I Lohnt sich heutzutage der Aufwand einer Portierung für MacOS Allgemeine Java-Themen 8
J Suchen von einer Scannereingabe in einem HashSet Allgemeine Java-Themen 1
M Konstruktor einer Methode Allgemeine Java-Themen 35
L Echtzeitdaten aus einer Webseite ziehen mit Java Allgemeine Java-Themen 19
V EMail, Attachments auslesen von einer Email Allgemeine Java-Themen 0
T Google Links in einer Liste Allgemeine Java-Themen 4
T Sinn einer toString Methode Allgemeine Java-Themen 3
P Durchlaufen einer Queue Allgemeine Java-Themen 9
J Größe einer CD ermitteln Allgemeine Java-Themen 10
L Operatoren Java Reflections: Alle Methoden einer Klasse aufrufen ohne Exceptions Allgemeine Java-Themen 5
H Länge einer verketteten Liste Allgemeine Java-Themen 4
B Quellcode einer Java libary finden um zu copy & paste'n Allgemeine Java-Themen 5
N Daten einer JCoTable in JTextArea anzeigen Allgemeine Java-Themen 7
sascha-sphw Java 9 module Zugriff auf eine resource einer anderen JAR Allgemeine Java-Themen 0
N Generic Type einer Generischen Klasse während der Laufzeit bekommen Allgemeine Java-Themen 2
E Erstellen einer Liste mit einer maximalen Menge an Elementen Allgemeine Java-Themen 13
M Wie kann ich ein int[] Array in einer Methode benutzen? Allgemeine Java-Themen 6
T Compiler-Fehler NoClassDefFoundError beim Laden einer Class Allgemeine Java-Themen 11
H Klassen LibGDX - Verschiedene Klassen als Value in einer Map Allgemeine Java-Themen 8
P Element einer Liste wurde hinzugefügt, aber es gibt keinen Zugriff Allgemeine Java-Themen 2
E Elemente innerhalb einer ArrayList vergleichen Allgemeine Java-Themen 33
J Einen Thread in einer Schleife Allgemeine Java-Themen 2
temi Java Programm aus einer DB laden und starten Allgemeine Java-Themen 2
J int Werte in einer anderen Klasse in Arrays speichern Allgemeine Java-Themen 3
S Hilfe bei dem Auslesen einer YAML Datei Allgemeine Java-Themen 8
D Warum kann ich eine (deflaut) Klasse aus einer Libary in einem anderen Projekt benutzen? Allgemeine Java-Themen 3
B Generelle Frage bei einer Webanwendung / Reduzierung von DB Abfragen Allgemeine Java-Themen 1
ReinerCoder Methode einer Klasse meldet Fehler "misplaced construct(s)" Allgemeine Java-Themen 13
L Fehler bei der Ausführung einer Jar Allgemeine Java-Themen 2

Ähnliche Java Themen

Neue Themen


Oben