Datensatz aus Datei ab bestimmter Stelle einlesen



  • Hallo - das hier ist mein erster Post und ich bin nicht nur in dem Forum sondern auch im Geschäft des Programmierens neu und bitte deshalb um Nachsicht, sollte ich die Antwort auf meine Frage an anderer Stelle überlesen haben

    Ich habe folgendes Problem:

    ofstream Output ("Startvektoren.svr", ios::binary);				                   //Richtungsvektoren in Datei speichern:
    for (unsigned int i=0; i<m_unTeilchenzahl; i++)
    	{
    	Output.write ((const char*) &m_A_EmissionsRichtungsvektoren[i].x, sizeof (m_A_EmissionsRichtungsvektoren[i].x));
    	Output.write ((const char*) &m_A_EmissionsRichtungsvektoren[i].y, sizeof (m_A_EmissionsRichtungsvektoren[i].y));
    	Output.write ((const char*) &m_A_EmissionsRichtungsvektoren[i].z, sizeof (m_A_EmissionsRichtungsvektoren[i].z));
    	};
    Output.close();
    

    speichert Richtungsvektoren in eine Datei. Das können ziemlich viele werden. Beim Auslesen behelfe ich mir zur Zeit noch mit

    ifstream Input ("Startvektoren.svr", ios::binary);                              //Richtungsvektoren aus Datei laden
    for (unsigned int i=1; i<=unTeilchenNr; i++)										//bis zu aktuellem Vektor lesen
    {
    	Input.read ((char*) &Vektor_current0, sizeof (Vektor_current0));
    }
    Input.close();
    

    , denn ich brauche immer nur einen davon, um damit weitere Rechenschritte zu vollführen.
    Nur: wenn es 5.000.000 Stück werden, dann dauert das ne Zeit, es muss ja jeder Wert (eine Struktur aus .x, .y, .z) eingelesen werden, bis man irgendwann bei dem gewünschten ist. Dafür ist die Schleife. Und elegant ist das natürlich nicht.

    Wie kann ich nun angeben, die ersten 3*8*x Bytes sollen übersprungen werden, damit ich direkt bei Byte x+1 lesen kann? (3*8, weil jede Struktur aus drei Doubles besteht)?

    Grüße
    yofu



  • Erstmal ist es vermutlich besser, die gesamte Struktur auch mit einem einzigen write()-Aufruf zu schreiben (der Compiler könnte noch Leerbytes zwischen die Elemente setzen, um sie an den Speichergrenzen auszurichten).

    Nun zu deinem Problem: Du kannst die Leseposition im Stream mit seekg() verschieben, um an deine Zielposition zu gelangen und den richtigen Datensatz rauszugreifen.



  • CStoll schrieb:

    Erstmal ist es vermutlich besser, die gesamte Struktur auch mit einem einzigen write()-Aufruf zu schreiben (der Compiler könnte noch Leerbytes zwischen die Elemente setzen, um sie an den Speichergrenzen auszurichten).

    Nun zu deinem Problem: Du kannst die Leseposition im Stream mit seekg() verschieben, um an deine Zielposition zu gelangen und den richtigen Datensatz rauszugreifen.

    Danke für die Antwort, CStoll!
    Die write-Schleife speichert ja nach und nach ein Array von Strukturen. Ich hatte damit bislang keine Probleme, werde es jedoch umstellen, um den Algorithmus in weniger Schritten zu realisieren - es könnte ja Auswirkungen auf die Geschwindigkeit haben.
    seekg() schaue ich mir mal an, ein Erfahrungsbericht folgt an dieser Stelle!



  • yofu schrieb:

    Die write-Schleife speichert ja nach und nach ein Array von Strukturen. Ich hatte damit bislang keine Probleme, werde es jedoch umstellen, um den Algorithmus in weniger Schritten zu realisieren - es könnte ja Auswirkungen auf die Geschwindigkeit haben.

    Gegen die Schleife an sich habe ich auch nichts einzuwenden - nur solltest du die drei write()-Aufrufe IN der Schleife zu einem zusammenfassen:

    for (unsigned int i=0; i<m_unTeilchenzahl; i++)
        {
        Output.write ((const char*) &m_A_EmissionsRichtungsvektoren[i], sizeof (m_A_EmissionsRichtungsvektoren[i]));
        };
    


  • CStoll schrieb:

    yofu schrieb:

    Die write-Schleife speichert ja nach und nach ein Array von Strukturen. Ich hatte damit bislang keine Probleme, werde es jedoch umstellen, um den Algorithmus in weniger Schritten zu realisieren - es könnte ja Auswirkungen auf die Geschwindigkeit haben.

    Gegen die Schleife an sich habe ich auch nichts einzuwenden - nur solltest du die drei write()-Aufrufe IN der Schleife zu einem zusammenfassen:

    for (unsigned int i=0; i<m_unTeilchenzahl; i++)
        {
        Output.write ((const char*) &m_A_EmissionsRichtungsvektoren[i], sizeof (m_A_EmissionsRichtungsvektoren[i]));
        };
    

    Ja - da hat sich ne unsinnige Verkomplizierung eingeschlichen 8).
    Das funktioniert blendend, genau wie sie es geschrieben haben. Und das gilt auch für seekg(). Ich verneige mein Haupt! 👍

    ifstream StartVektorInput;													//Richtungsvektoren aus Datei laden
    StartVektorInput.open("Startvektoren.svr", ios::binary);                     
    
    StartVektorInput.seekg (3*8*(unTeilchenNr-1));                              // vorskippen auf Position des derzeitigen Vektors (Struktur aus 3 doubles)
    StartVektorInput.read ((char*) &Vektor_current0, sizeof (Vektor_current0));
    
    StartVektorInput.close();
    


  • Jetzt solltest du noch das "3*8" ersetzen durch sizeof(vector_t), dann ist es schon fast perfekt 😉



  • CStoll schrieb:

    Jetzt solltest du noch das "3*8" ersetzen durch sizeof(vector_t), dann ist es schon fast perfekt 😉

    Zu Befehl! Dann habe ich wenigsten 5 perfekte Zeilen in dem Programm 😃 (...und noch was gelernt).

    hier nochmal die ganze Herrlichkeit:

    ifstream StartVektorInput;													//bestimmten Vektor(Struktur) aus Datei laden
    StartVektorInput.open("Startvektoren.svr", ios::binary);                     
    
    StartVektorInput.seekg (sizeof(Vektor_current0)*(unTeilchenNr-1));           // vorskippen auf Position des gesuchten Vektors
    StartVektorInput.read ((char*) &Vektor_current0, sizeof (Vektor_current0));
    
    StartVektorInput.close();
    

    und vielen Dank! Klasse Forum hier!
    Nun hoffe ich dass ich auch mal Fragen finde, die anfängerhaft genug sind, dass ICH sie beantworten kann, aber das gestaltet sich gar nicht einfach (und wenn doch, bin ich nicht schnell genug).

    Grüße
    yofu


Anmelden zum Antworten