Forum: PC-Programmierung [Qt/C++] Arbeiten mit SQLite/XML in ZIP-Dateien


von Gelöscht (kami89)


Lesenswert?

Hallo zusammen,

Für eine Qt/C++ Software bin ich mir ein Dateiformat für die 
Projektdateien am überlegen. Das Programm soll die Projektdateien dann 
laden, bearbeiten und wieder speichern können, so wie z.B. Textdokumente 
in LibreOffice.

Ein Projekt besteht aus einer SQLite Datenbank, ein paar XML Dateien und 
ein bisschen Kleinkram. Alles zusammen höchstens ein paar wenige 
Megabyte gross. Um das alles in einer einzigen Datei zu speichern, kam 
mir natürlich sofort ZIP in den Sinn.

Leider gibt es in Qt anscheinend keine Klassen für den Umgang mit ZIP 
Dateien. Nun habe ich mal ein bisschen mit "QuaZip" experimentiert, 
damit kann man ZIP Dateien lesen und speichern.

Allerdings frage ich mich, wie ich in QSqlDatabase eine SQLite Datenbank 
laden kann, welche komprimiert im ZIP-Archiv liegt. Weiss jemand, wie 
und ob das überhaupt möglich ist?

Eine andere Idee wäre es, beim Öffnen eines Projektes die ZIP Datei in 
einem temporären Verzeichnis zu entpacken, dort dann die Bearbeitung 
durchzuführen, und beim Speichern dieses Verzeichnis wieder zu zippen 
und die ursprüngliche Datei zu überschreiben. Ein positiver Nebeneffekt 
dieser Variante ist, dass unter Umständen nach einem Programmabsturz die 
nicht gespeicherten Änderungen wiederhergestellt werden können, da sie 
noch im temporären Verzeichnis liegen.

Was meint Ihr, ist das eine gute Idee?
Hat jemand noch andere Ideen? Oder eigene Erfahrungen?

Das Komprimieren mit ZIP ist übrigens kein Kriterium, das war einfach 
meine einzige Idee. Die Lösung muss unter Windows, Linux und Mac 
zuverlässig funktionieren und sollte kein Gebastel sein.

Bin für jeden Tipp dankbar!

mfg

von Christian (Gast)


Lesenswert?

Du könntest auch alle Daten in der sqlite-Datenbank abspeichern, zB als 
Blobs.
Die Daten, die du da rein schreibst könntest du auch komprimieren.

von Gelöscht (kami89)


Lesenswert?

Christian schrieb:
> Du könntest auch alle Daten in der sqlite-Datenbank abspeichern, zB als
> Blobs.
> Die Daten, die du da rein schreibst könntest du auch komprimieren.

Stimmt, auf diese Idee bin ich auch schon gekommen. Allerdings ist das 
nicht wirklich professionell sondern eher ein Gebastel. Daher habe ich 
diese Idee dann gleich wieder verworfen... ;-)

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Urban B. schrieb:
> Allerdings frage ich mich, wie ich in QSqlDatabase eine SQLite Datenbank
> laden kann, welche komprimiert im ZIP-Archiv liegt. Weiss jemand, wie
> und ob das überhaupt möglich ist?

Sofern die Datenbank in den Arbeitsspeicher passt:
Aus der Zip-Datei genau dort hineinladen, dann mit SQLite eben nur im 
Speicher nutzen und aus dem Speicher wieder in die Zip-Datei 
zurückschreiben.

von Gelöscht (kami89)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Sofern die Datenbank in den Arbeitsspeicher passt:
> Aus der Zip-Datei genau dort hineinladen, dann mit SQLite eben nur im
> Speicher nutzen und aus dem Speicher wieder in die Zip-Datei
> zurückschreiben.

Von der Grösse der DB wäre das kein Problem. Aber wie stellst du dir das 
Laden und Speichern vor? Man kann ja eine SQLite DB im RAM erzeugen, 
aber wie kann ich dann eine bereits vorhandene *.sqlite3 laden? Die 
einzige Möglichkeit, die mir in den Sinn kommt, ist der Umweg über den 
Import/Export von *.sql Dateien aber irgendwie ist das auch wieder ein 
Gebastel...

Gibts Meinungen zur Variante mit dem Entpacken in einen temporären 
Ordner?
Hat schonmal jemand gesehen dass andere Programme das auch so machen?

von Malte S. (maltest)


Lesenswert?

Disclaimer: habe keine Erfahrung damit, war aber mal hierüber 
gestolpert: http://www.sqlite.org/vfs.html

EDITH SAGT: Wahlfreier Zugriff und Größenänderungen machen einen 
Direktzugriff in eine ZIP allerdings nicht unbedingt performant.

von Gelöscht (kami89)


Lesenswert?

Malte S. schrieb:
> EDITH SAGT: Wahlfreier Zugriff und Größenänderungen machen einen
> Direktzugriff in eine ZIP allerdings nicht unbedingt performant.

Stimmt wohl...

Ich bin jetzt am schauen ob ich statt der SQLite Datenbank auch eine 
XML-Datei verwenden soll. Dann wäre immerhin das Problem mit dem Laden 
der Datenbank in QSqlDatabase vom Tisch. Eine XML im ZIP kann ich 
problemlos ohne den Umweg über die Festplatte lesen.

Allerdings ist QuaZip irgendwie auch nicht so das gelbe vom Ei, es 
fehlen anscheinend Funktionen um Dateien im ZIP-Archiv zu löschen oder 
zu überschreiben.

Momentan sehe ich zwei Möglichkeiten:
Entweder die bereits erläuterte Variante, wo die ZIP-Datei temporär 
entpackt und beim Speichern des Projektes wieder gezippt wird.
Oder einen ganz anderen Ansatz, den ich noch nicht kenne :-)

Grundsätzlich suche ich einfach eine Art Container für Dateien inkl. 
Verzeichnisstruktur. Wünschenswert wäre natürlich, wenn ich die Klassen 
QFile und QDir für den Zugriff verwenden könnte. Sowas in der Art hat es 
bei Qt sogar mal gegeben, nannte sich "QAbstractFileEngine". Wurde aber 
in QT5 leider wieder entfernt...

Naja...wird dann wohl auf das Entpacken in ein temporäres Verzeichnis 
herauslaufen. Trotzdem Danke für die Antworten!

mfg

von Markus B. (markusborti)


Lesenswert?

Grüß dich,

ich hätte noch die Idee (die zumindest auf Linux ohne weiteres 
funktionieren sollte), dass du es in eine ISO-Datei packst und diese zur 
Laufzeit einbindest, bearbeitest und schließlich wieder abspeicherst.

Grüße

von Gelöscht (kami89)


Lesenswert?

Hallo Markus,

Markus Borti schrieb:
> ich hätte noch die Idee (die zumindest auf Linux ohne weiteres
> funktionieren sollte), dass du es in eine ISO-Datei packst und diese zur
> Laufzeit einbindest, bearbeitest und schließlich wieder abspeicherst.

Interessante Idee, aber um das in Qt zu nutzen wäre vermutlich ein 
Systemaufruf notwendig um die ISO zu mounten (nehme ich mal an). Ob das 
dann immer zuverlässig funktioniert... Unter Linux würde das vielleicht 
noch gehen, aber unter Windows?

Wenn ich schon mit Qt eine Software schreibe, sollte die dann auch unter 
Windows und Mac funktionieren (auch wenn mir persönlich eine 
Linux-Version reichen würde ;-)

Ausserdem halte ich ISO-Images für einen Overkill, bei Projektdateien 
die durchschnittlich vielleicht so 500KB klein sind :-)

von Malte S. (maltest)


Lesenswert?

Na unter Linux ist /tmp wenigstens i.d.R. als tmpfs im RAM und wird 
spätestens beim nächsten Start wieder frisch gemacht bzw. sowieso 
automatisch bereinigt.
Tempfiles unter Windows riechen immer so nach Chaos-Verzeichnis, von 
dessen Existens der Normaluser nicht mal etwas ahnt und das gerne zur 
persistenten Müllhalde wird. Fehlende Bereinigung durch verbuggte 
Programme und deren oder des OS Abstürze führen zu Patina und dann so 
seltsamen Dingen wie dem Bereinigungsassistenten, der direkt noch 
Software zur Deinstallation vorschlägt, die wider Windows Installers 
schlechteren Wissens sehr wohl häufiger mal verwendet wird.

von Malte S. (maltest)


Lesenswert?

Urban B. schrieb:
> Interessante Idee, aber um das in Qt zu nutzen wäre vermutlich ein
> Systemaufruf notwendig um die ISO zu mounten (nehme ich mal an). Ob das
> dann immer zuverlässig funktioniert... Unter Linux würde das vielleicht
> noch gehen, aber unter Windows?

Das Mounten erfordert root bzw. CAP_SYS_ADMIN oder einen mit 
entsprechenden Rechten vorkonfigurierten Automounter. Ähnlich unter 
Windows (>= Vista) wäre mit Bordmitteln noch das Mounten eines WIM, 
erfordert aber auch Rechte.
Aber ob's das Wert ist? Denke kaum.

Urban B. schrieb:
> Allerdings ist QuaZip irgendwie auch nicht so das gelbe vom Ei, es
> fehlen anscheinend Funktionen um Dateien im ZIP-Archiv zu löschen oder
> zu überschreiben.

Weil genau das die Operationen sind, die sich in einem Fake-Filesystem 
nicht so hübsch machen. Da werden an einer Stelle Löcher in die Datei 
gerissen und hinten wieder was drangepappt. Dann muss der große 
Staubsauger kommen und das Loch unter entsprechender Anpassung 
dateiinterner Zeiger ausbügeln. Also ungefähr all das, wozu eben ein 
Dateisystem da ist. Nur, dass das Dateisystem ohne mit der Wimper zu 
zucken Bereiche als ungenutzt markieren und mit einer gewissen 
Fragmentierung leben, den Rest später im Hintergrund erledigen kann. 
Innerhalb einer Datei möchte man das ja eher nicht. "mbox"-ähnliche 
Mailboxen leiden seit jeher darunter, weshalb maildir etc. entworfen 
wurden, um die Hausarbeit dem darin besser bewanderten Dateisystem zu 
überlassen.
Datenbanken haben dasselbe Problem, aber immerhin liegt das da noch 
ziemlich im Kernbereich und rechtfertigt somit den ganzen Aufwand.
Ob das aber im Rahmen deiner Anwendung zutrifft oder es nicht besser 
wäre, mit einem Haufen Dateien zu leben? Aber ansonsten nichts gegen 
dein Anliegen, das ist schon sehr verständlich, würde nur nicht zu weit 
gehen mit sowas. Je nachdem, wie oft Änderungen gemacht werden. Hast du 
einen klassischen Workflow aus Laden, lange bearbeiten, ab und an 
Wiederherstellungskram speichern, am Ende alles speichern? Dann okay. 
Wenn du eher oft zwischendurch Änderungen machst und gesichert haben 
willst, nutze das Dateisystem.

von Gelöscht (kami89)


Lesenswert?

Jup, temporäre Dateien sind häufig ziemlich lästig, da stimme ich dir 
zu. Wenn die Software bei jedem Programmstart aber erstmal schaut ob 
noch Müll rumliegt, sollte sich das in Grenzen halten. Und nebenbei hat 
man dann auch gleich die Möglichkeit, ungesicherte Projekte nach einem 
Absturz wiederherzustellen.

Auch das mit der Fragmentierung innerhalb der Zip-Datei ist etwas, das 
mir Kopfschmerzen bereitet. Egal welche Idee ich habe, ich bin nie so 
wirklich zufrieden. Deshalb habe ich diesen Thread aufgemacht :-)

Um die Katze aus dem Sack zu lassen:
Es geht um eine EDA-Software, also Schaltplan- und Layoutdesign. 
Aufgrund einer Kombination aus Neugier, Langeweile und Unzufriedenheit 
bezüglich des Angebotes auf dem Markt bin ich jetzt ein bisschen am 
experimentieren, was eigenes auf die Beine zu stellen. Ich habe schon 
diverse Versuche quasi als Machbarkeitsstudie durchgeführt, und jetzt 
bin ich dabei, die Dateiformate für Projektdateien und Bibliothek zu 
definieren.

Die Anforderungen an das Dateiformat sollten damit ungefähr klar sein. 
Halt wie z.B. eine Eagle Projektdatei (schlechtes Beispiel da dort Board 
und Schaltplan getrennt gespeichert werden, was ich aber NICHT machen 
wollte aufgrund "schlechter Erfahrungen" [Inkonsistenz]).

Vorher hatte ich aber noch eine ganz andere Idee. Angenommen, die 
Projekte werden nicht gezippt sondern liegen in Form von XML-Dateien in 
einem Verzeichnis. Dann könnte man bei einem gescheiten Design der 
XML-Dateien eigentlich mit einem Versionsverwaltungssystem sogar ein 
Projekt verwalten. Da so nicht Binärdaten (z.B. ZIP-Dateien) verwaltet 
werden, könnten theoretisch auch mehrere Leute gleichzeitig am gleichen 
Projekt arbeiten (z.B. jeder an einer Schemaseite).

Allerdings frage ich mich, ob das in der Praxis auch eingesetzt werden 
würde...

Ungezippte Projektdateien haben schon diverse Vorteile. Andererseits 
sind einzelne (z.B. gezippte) Projektdateien "schöner anzuschauen" (im 
Dateimanager), wirken einfach aufgeräumter und können einfacher 
untereinander ausgetauscht werden (per Mail verschicken usw.).

Irgendwie stehe ich wieder total am Anfang. Ich habe keine Ahnung wie 
ich die Projekte speichern soll... ;-)

mfg

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.