Dateien binär in Klassen speichern und dann serialisieren



  • Hallo zusammen,

    ich hatte vor ein paar Jahren mal eine Idee für ein Programm das unter Linux laufen soll. Unzwar habe ich erst gestern versehentlich eine wichtige Datei gelöscht. Deswegen wollte ich neben rm noch ein anderes Programm schreiben das wie der Papierkorb unter Windows funktioniert. Ich hatte ein paar Ansätze aber ich habs einfach nicht umsetzen können. Lag wohl auch daran das meine Ansätze vielleicht nicht so gut waren.
    Jetzt habe ich mir nochmal Gedanken gemacht und mir was überlegt und wollte von euch Wissen ob das ein guter Ansatz ist.

    Ich habe vor, Dateien die gelöscht werden sollen, vorher in einer Klasse zu speichern. Die Datei soll die binären Daten in die Klasse schreiben. Die Klasse bekommt dann Informationen mitgegeben wie der Pfad wo die Datei lag oder die Dateigröße. Anschließend soll die Klasse dann mit den binären Daten und den Informationen serialisiert werden. Die Klasse wird dann irgendwo auf der Platte gespeichert.

    Der Grund warum ich mir das so überlegt habe ist, weil ich dann eine Funktion einbauen kann um mit einem Parameter alle gelöschten Dateien auflisten zu können mit den jeweiligen Informationen. Einfaches verschieben der Dateien in einen anderen Ordner finde ich blöd, da man das auch einfach mit mv machen kann. Mit einem anderen Parameter könnte man dann einzelne oder mehrere Dateien wiederherstellen.

    Ich weiß natürlich, dass es bei großen Dateien problematisch wird. Daher würde ich die Größe von den Klassen und den Dateien die gelöscht werden sollen auf ca. 2GB beschränken. Bei großen Dateien könnte der Vorgang auch recht lange dauern.

    Das ganze wollte ich vielleicht mit QT5 lösen.

    Kann mir da jemand vielleicht noch ein paar Tipps geben? Ist das so umsetzbar? Macht das Sinn? Sollte ich was beachten?



  • Und das willst du mit QT lösen? Das bekommst du in einfachem C/C++ mit der Standardlib hin, soll ja eh auf Linux laufen, da brauchst du keine Portabilität.

    Der Ansatz der Serialisierung verstehe ich nicht so ganz. Du kannst die Daten auch direkt 1:1 in deinen "Papierkorb" verschieben, und dann eine Zuordnungsdatei, die die Metainformationen beinhaltet, für jeden Eintrag erstellen. Das spart dir später lästiges Gefummel, wenn du Operationen durchführen willst, die eher trivial sind. Am Besten als Textformat, damit du, wenn du später rausfindest, dass dir ein Eintrag fehlt, da manuell was editieren kannst (oder auch automatisch anpassen lassen kannst).

    Wenn du dann die Klassen mit deinem Ansatz speichern willst, musst du darauf achten, dass deine Serialisierung bei Zeigern/Objekten ebenfalls serialisiert - sonst hast du am Ende nur temporär valide (und damit für dich unbrauchbare) Dateien rumliegen, weil nicht der Pointer 0x12345678, sondern das Objekt dahinter bearbeitet werden sollte.

    Nur meine 2 Cents. Bin mir sicher, dazu gibt es noch einiges zu sagen.



  • Das erste was ich mir überlegt hatte war die Dateien in einen Ordner zu verschieben und die Informationen in einer noSQL Datei zu speichern, aber irgendwie konnte ich mich nicht damit anfreunden.
    Der Grund ist das der User schnell mitbekommt das die Dateien nur verschoben wurden und später anstatt den Kommandobefehl auf der Konsole die Dateien wiederherstellt indem er sie selber schnell wieder verschiebt. Das macht es dann in meinen Augen Sinnfrei Informationen über die Dateien irgendwo abzuspeichern. Weil verschieben kann ich sie auch selber.



  • Bennisen schrieb:

    Der Grund ist das der User schnell mitbekommt das die Dateien nur verschoben wurden und später anstatt den Kommandobefehl auf der Konsole die Dateien wiederherstellt indem er sie selber schnell wieder verschiebt.

    Dann lass ihn doch. Wenn die Aufgabe an sich so trivial ist, dann solltest du sie nicht künstlich komplizierter machen, als sie ist.

    Wenn du's richtig kompliziert haben willst, erstellst du einen Deamon, der im Hintergrund die Dateien zu gz oder gar xz (-9e, alles andere ist Kindergeburtstag :)) komprimiert.

    Bennisen schrieb:

    Das macht es dann in meinen Augen Sinnfrei Informationen über die Dateien irgendwo abzuspeichern. Weil verschieben kann ich sie auch selber.

    Werden die meisten aber nicht machen. Die machen eher `rm bla` und fluchen danach.



  • Wenn du unbedingt die Datei verfriemeln willst, dann kopiere sie doch einfach und benutze append fuer die restlichen Infos. Die sollten dann entweder eine konstante Groesse haben oder du schreibst ganz ans Ende nochmal die Groesse der Daten als z.b. 32Bit Wert.



  • Bennisen schrieb:

    Kann mir da jemand vielleicht noch ein paar Tipps geben? Ist das so umsetzbar?

    Ja.

    Bennisen schrieb:

    Macht das Sinn?

    Nein.

    Bennisen schrieb:

    Sollte ich was beachten?

    Ja. Und zwar dass es schon einen Grund hat dass quasi alle Lösungen die es gibt einfach nur die Files verschieben: Weil das einfach am schnellsten ist. Und natürlich ist es praktisch wenn man im Falles des Falles auch ohne Hilfe des speziellen Tools noch auf die Files im Mülleimer zugreifen kann. Den Inhalt der Files irgendwie zu modifizieren wäre daher eher keine gute Idee -- selbst wenn man nur ein einziges Byte anhängt.

    Und es hält dich nichts davon ab weitere Informationen in z.B. einer Datenbank abzuspeichern.

    Oder auch einfach in extended attributes. Das wäre vermutlich der Weg den ich als erstes versuchen würde. Gibt zwar unter Linux bzw. den unter Linux gängigen File-Systemen ein paar Caveats (z.B. könnte es theoretisch passieren dass kein Platz mehr für "dein" Attribute ist), aber ich denke es sollte gut funktionieren.



  • Ok, ich werde das hier erwähnte mal probieren.

    Ich hätte da noch ein paar andere Fragen und will dafür kein neuen Thread auf machen.

    Gibt es eine Anleitung wie ich Shellprogramme entwickle? Zum Beispiel wie verarbeite ich die Parameter im Quellcode oder was mach ich wenn ich mit dem entwickeln fertig bin? Will das Programm dann auch gerne veröffentlichen.



  • Bennisen schrieb:

    ich hatte vor ein paar Jahren mal eine Idee für ein Programm das unter Linux laufen soll. Unzwar habe ich erst gestern versehentlich eine wichtige Datei gelöscht. Deswegen wollte ich neben rm noch ein anderes Programm schreiben das wie der Papierkorb unter Windows funktioniert.

    Hmm, also sobald Du den Papierkorb hast, wirste sagen "Upps, hab gestern eine wichtige Datei aus Versehen überschrieben/verändert."
    Also eigentlich müsstest Du nicht nur alle Löschungen abfangen, sondern auch alle Änderungen irgendwelcher Art.

    Vielleicht ist das besser eine Aufgabe des Dateisystems.
    https://btrfs.wiki.kernel.org/index.php/Autosnap
    http://www.nilfs.org/
    und so weiter…



  • Bennisen schrieb:

    Gibt es eine Anleitung wie ich Shellprogramme entwickle? Zum Beispiel wie verarbeite ich die Parameter im Quellcode oder was mach ich wenn ich mit dem entwickeln fertig bin? Will das Programm dann auch gerne veröffentlichen.

    Du baust zuerst die Kernfunktionalität, und achtest darauf, dass dein Interface einfach zu verstehen und zu erweitern ist.
    Sobald die Hauptfunktionalität bereitsteht, kannst du dir Gedanken darüber machen, wie du einem User Zugriff auf den Code bietest.

    Beispiel: du hast eine Hauptbibliothek für trivialere Aufgaben (Dateien einlesen, Nummern parsern, Dateien zurückschreiben, etc). Diese API verwendest du, um ein Programm zu schreiben, welches eine bestimmte Funktion durchführt - sagen wir mal, genau das, worum es ursprünglich bei dir ging.

    Du hast dann also einen Haufen auskommentieren und nicht-auskommentierten Code in deiner Main-Funktion, der immer bestimme Funktionen erfüllt, und fragst dich, "wie bringe ich Ordnung in das Chaos"? Dann schiebst du den Code in eine zweite Quellcodedatei, achtest darauf, dass jeder Code-Abschnitt sauber getrennt wird, sodass eine Funktion genau eine Aufgabe erfüllt, und das möglichst gut. Wenn du Code doppelt hast, schreibst du eine weitere Funktion/Makro, die diesen Code beinhaltet - damit vermeidest du später, etlichen Redundanzen hinterherzulaufen,

    Schließlich ist deine Main leer, der Code befindet sich in der separaten Quellcodedatei, und das Interface, welches du im Header stehen hast, ist nett und einfach. Wenn du dieses Stadium erreicht hast, dann kannst du dir überlegen, ein Programm zu schreiben, welches dem User erlaubt, Funktionen auszuwählen.

    Merke: wenn du abgesehen vom Argument-parsing Code noch Komplexität in deinem Hauptprogramm hast, welches du abgewandelt in dein API packen könntest, dann ist dein API nicht vollständig. Dein Programm soll nur eine Shell sein, deine separate Bibliothek soll rocken.

    Vergiss nicht: keiner, absolut keiner mag externe Abhängigkeiten. In der Regel arbeitest du immer mit den Werten und Argumenten, die dir der Aufrufer an deine Funktionen weitergibt. Es gibt Ausnahmen, aber diese müssen notwendig sein, damit sie gerechtfertigt sind. Wenn eine Bibliothek eine von außen nicht einsehbare statische Variable ändert, dann muss das seinen Grund haben (handelt sich z.B. um einen Mutex, der Initialisiert/gelockt/released werden muss).

    Für Linux findest du unter dem Stichwort "getopt" einen ganzen Haufen an Dokumentation. Aber das Parsen der Argumente musst du machen, getopt kann nur ein bisschen Ordnung in deinen Code bringen.



  • Bennisen schrieb:

    Gibt es eine Anleitung wie ich Shellprogramme entwickle? Zum Beispiel wie verarbeite ich die Parameter im Quellcode oder was mach ich wenn ich mit dem entwickeln fertig bin? Will das Programm dann auch gerne veröffentlichen.

    Ich würde als erstes mal Programmieren lernen.
    Üblicherweise fangen die meisten Bücher/Tutorials/... eh mit Shellprogrammen an.



  • hustbaer schrieb:

    Bennisen schrieb:

    Gibt es eine Anleitung wie ich Shellprogramme entwickle? Zum Beispiel wie verarbeite ich die Parameter im Quellcode oder was mach ich wenn ich mit dem entwickeln fertig bin? Will das Programm dann auch gerne veröffentlichen.

    Ich würde als erstes mal Programmieren lernen.
    Üblicherweise fangen die meisten Bücher/Tutorials/... eh mit Shellprogrammen an.

    Hab 2 ausführliche Bücher hier. Programmiert habe ich auch schon in C++, aber immer wieder mal nur ein bisschen. Muss mich erstmal wieder etwas reinarbeiten. Viele Funktionen die ich brauche bietet mir ja zum Glück die Boost Lib.


Log in to reply