eine Array einer großen Struktur sicher/laden



  • Hallo,

    ich hab hier einen großen Datensatz und möchte den wegsichern in eine Datei, die Datei dient auch dafür um diesen Datensatz später wieder einzulesen und die Werte an die entsprechenen Positionen zu schreiben. So, ich hab jetzt schon einige Sachen ausprobiert. Z.B. jedes einzelne Element des Datensatzes mit strcat zu einem großen string zu schreiben und jedes Element daten[i] in eine separte Datei zu schreiben, dauert logischerweise sehr lange, dann hatte ich die Idee mit malloc einen sehr großen Datenpuffer zu erzeugen und hab versucht ebenfalls die Daten mit strcat anzuhängen, da scheint es dann einen Überlauf zu geben. Was ist eurer Meinung nach ein vorteilhafter Weg um diese Struktur wegzusichern und wieder zu laden, d.h. die Daten sollten ebenfalls so formatiert sein, daß nicht nur das wegsichern flott geht, sonder auch das zuordnen beim einlesen. Ich danke euch schon mal für eure Hilfe. Hier also meine Struktur wie ich ihn in meiner Headerdatei angelegt habe. Falls diese Struktur unvorteilhaft ist, müsste ich sie notfalls auch ändern, einige von euch würden mir bestimmt auch Listen vorschlagen, da ich da aber wenig Plan habe möchte ich das nach Möglichkeit erst mal vermeiden, da mein Programm mit der jetzigen Struktur bis auf das sichern und laden ja ganz gut funktioniert. Ok hier die Struktur der Daten:

    typedef struct{
    	char		*name;
    	int		position;
    }sub_data_1;
    
    typedef struct{
    	int		*name;
    	int		value_1;
    	int		value_2;
    }sub_data_2;
    
    typedef struct{
    	char		name_1[64];
    	char		name_2[64];
    	char		name_3[64];
    	char		name_4[64];
    	char		name_4[64];
    	char		name_5[64];
    	char		name_6[64];
    	char		name_7[64];
    	char		name_8[64];
    	char		name_9[64];
    	char		name_10[64];
    	int		zahl_1;
    	int		zahl_2;
    	int		zahl_3;
    	int		zahl_4;
    	int		zahl_5;
    	int		zahl_6;
    	int		zahl_7;
    	int		zahl_8;
    	int		zahl_9;
    	int		zahl_10;
    	sub_data_1	sub_1[128];
    	sub_data_2	sub_2[128];
    	boolean		valid;
    }datensatz_t;
    
    extern	datensatz_t		daten[20480];
    


  • Du hast in der ersten Struktur einen Zeiger auf char*. Beim Speichern und Einlesen musst du die exakte Anzahl der Bytes kennen, die du dann irgendwo separat speichern musst.
    Am einfachsten wäre, wenn du ein Array konstanter Größe nimmst.

    Ist das mit dem Zeiger auf int in der zweiten Struktur beabsichtigt ?
    Ich glaub das soll wohl auch ein char* sein oder ?
    Denn die Adressen im Speicher sind mit jedem neuen Programmstart nicht unbedingt immer die gleichen.

    Naja, ansonsten würd ich halt wenn möglich in den Strukturen Variablen konstanter Länge, also ohne Zeiger benutzen. Dann ist speichern und einlesen ganz leicht mit fwrite und fread, ohne große Klimmzüge machbar.

    Für jede Struktur einen separaten fwrite/fread Befehl.



  • Ja du hast Recht, daß muß ein Zeiger auf char sein, aus RAM Speichertechnischen Gründen hab ich da auch Zeiger genommen und fordere den Speicherplatz erst dann mit malloc an wenn diese Elemente auch wirklich beschrieben weren müssen was meist nicht der Fall ist. Es müssen von der Hauptstruktur auch nur die belegten Elemente, meist nur ca 10000 gesichert werden. Ich hab da jetzt mal ein paar Tests mit verschiedenen Ansätzen gemacht. Also wenn ich jede Hauptstruktur in eine separate Datei abspeichere benötige ich je nach "Füllmenge" der Struktur, zwischen 8 und 10 Sekunden, es wurden damm ca 3500 einzeldateien erzeugt. Dann hab ich die Daten mit "ab+" in eine einzelne Datei geschrieben. Auch da benötige ich zwichen 5 und 10 Sekunden. Als Zwischenschritt wurde für beide Methoden ein 64000 Byte großer Char Buffer benutzt in dem ich die Daten mit strcat reinkopiert habe und danach wurde der Buffer weggesichert. Als dritte Möglichkeit hatte ich noch versucht einen sehr großen Charbuffer mit strcat mit den Elementen zu füllen und dann auf einmal in eine Datei zu schreiben, da hat mein Proggy schon über 10 Minuten rumgenudelt um alle Daten mit strcat in den riesen Buffer zu schreiben. Naja ich denke mal daß ich irgendwo beim Aufbereiten der Daten Zeit sparen könnte das mit strcat dauert wohl schon lange. Weiß einer Alternativen? Bitte nicht ASM da kenn ich mich net aus.



  • Also, am schnellsten denke ich mal, würde es mit fwrite/fread gehen.
    Du kannst mit fwrite/fread mehrere Strukturen eines Typs in einem Rutsch in eine Datei schreiben und wieder auslesen.
    Wie schon erwähnt, am einfachsten und schnellsten ist es wenn du Variablen konstaner Länge in den Strukturen benutzst.

    Siehe Deklaration von fwrite:
    size_t fwrite( const void *buffer, size_t size, size_t count, FILE *stream );

    Mit buffer kannst du auf eine deiner Strukturen zeigen. Size ist die Größe einer Struktur und mit count gibst du an, wie viele Strukturen du speichern willst.
    Stream ist der Dateizeiger.
    Ich schreib dir mal ein Beispiel. Das folgende Codeschnipsel würde dir 100 Strukturen in die Datei Test.dat in einen Rutsch speichern.

    datensatz_t datensatz;
    FILE *fp = fopen( "Test.dat", "wb" );
    fwrite( &datensatz, sizeof(datensatz), 100, fp );
    fclose(fp);
    

    Gruß,
    p.



  • proggingmania schrieb:

    Ich schreib dir mal ein Beispiel. Das folgende Codeschnipsel würde dir 100 Strukturen in die Datei Test.dat in einen Rutsch speichern.

    datensatz_t datensatz;
    FILE *fp = fopen( "Test.dat", "wb" );
    fwrite( &datensatz, sizeof(datensatz), 100, fp );
    fclose(fp);
    

    Gruß,
    p.

    Kleiner Tip: Wenn du 100 Strukturen speichern willst, solltest du auch so viele stehen haben - du speicherst den Inhalt von datensatz und irgendwelchen 99*sizeof(datensatz_t) Byte Datenmüll:

    datensatz_t tabelle[100];
    FILE* fp=fopen("Test.dat","wb");
    fwrite(tabelle,sizeof(datensatz_t),100,fp);
    fclose(fp);
    

    Außerdem funktioniert dieser Ansatz nur, wenn alle Daten direkt im Objekt liegen - die char* name; Elemente müssen noch gesondert gespeichert werden.



  • CStoll schrieb:

    Kleiner Tip: Wenn du 100 Strukturen speichern willst, solltest du auch so viele stehen haben - du speicherst den Inhalt von datensatz und irgendwelchen 99*sizeof(datensatz_t) Byte Datenmüll:

    Logisch !

    Gruß,
    p.


Anmelden zum Antworten