schneller Dateizugriff



  • @enno-tyrant
    Das wäre nicht auf einen Rutsch. Sondern auch nur zeilenweise.

    #include <sstream>
    #include <fstream>
    #include <iostream>
    
    std::fstream::pos_type GetFilesize( std::string const & filename )
    {
      std::ifstream ifs(filename.c_str());
      ifs.seekg(0,std::ios::end);
      std::fstream::pos_type size = ifs.tellg();
      ifs.seekg(0,std::ios::end);
      return size;
    }
    
    int main()
    {
      // Öffnen der datei 
      std::ifstream ifs("test_str.c");
      // Herausfinden wie groß sie ist
    
      unsigned sizeoffile = GetFilesize("/root/test_str.c");
    
      // benötigten speicher allokieren
      char * tmp = new char[sizeoffile + 1] ;
    
      // Einlesen der Datei auf einen Rutsch
      ifs.read(tmp,sizeoffile);
    
      ifs.close();
    
      // Vorsichtshalber mal den Datenpuffer hinten begrenzen
      tmp[sizeoffile] = 0x0;
    
      // Kopieren der daten
      std::istringstream istr(tmp);
    
      // Löschen des Puffers
      delete tmp;
    
      // Ganz normal wie mit ifstream arbeiten...
      ...
    }
    


  • du machst alles in etwa weiter wie bisher (getline()) nur mit dem stringstream und nicht mit der datei



  • Ich hab auch mal ne Datei auf einmal einlesen müssen,
    ging um wiedergabe von MP3s, und da zeigte sich das die C Funktionen
    mit FILE* um einiges schneller waren als die streams.

    Devil



  • Vielen Dank für die Hilfen! Ich hoffe etwas davon beschleunigt die Arbeit. Ansonsten dauert die Sache halt etwas. Zum Auslesen einer 30MB Datei benötigt die Geschichte so wie sie jetzt ist nämlich so gefühlte 2min. 4 von diesen Dateien müßte ich einlesen. Wenn die Sachen alle nicht helfen brauch man halt Geduld.



  • Jetzt bin ich endlich zum Ausprobieren gekommen. Ich habe da jetzt allerdings ein Problem. Ich möchte in meinem Hauptprogramm 5 istringstream Objekte anlegen, in die ich jeweils mit demselben Unterprogramm eine Datei einlese, damit ich diese istringstream Objekte dann in anderen Unterprogrammen weiterverwenden kann. Leider funktioniert das mit meiner Übergabe aber nicht. Wenn ich ein istringstream Objekt direkt im Unterprogramm erzeuge und dann die eingelesene Datei direkt beim Erzeugen des Objektes in das Objekt kopiere mit Hilfe des Konstruktors geht es. Wenn ich das Objekt allerdings übergebe muß ich dieses Kopieren ja mit einer Funktion machen, und das tut irgendwie nicht. Ich habe probiert mit read aus der char Variablen in das istringstream Objekt zu lesen, aber das geht nicht. Das Objekt bleibt dann im Hauptprogramm leer. Wie muß ich so eine Übergabe machen und mit welcher Funktion bekomme ich dann die Daten aus der char-Variablen in mein istringstreamobjekt?



  • Nabend,

    Windows bietet doch bestimmt auch die Moeglichkeit des Memory Mapped I/O, oder?

    Scheint mir hier recht praktikabel zu sein, allerdings habe ich keine Ahnung,
    wie das unter Windows funktioniert. Natuerlich hat das dann auch nichts mehr mit
    Standard C++ zu tun.

    Ansonsten waere es sehr gut, wenn du mal was Code posten koenntest.

    mfg
    v R



  • Also ich hatte mir das in etwa so gedacht:

    im main teil:

    void dateilesen(char*,istringstream*);

    istringstream istr;
    dateilesen("beispiel.txt",istr);

    unterprogramm:

    void dateilesen(char* dateiname,istringstream* istr)
    {
    unsigned size=0;
    ifstream datei;
    datei.open(dateiname,ios_base::in);
    datei.seekg(0,ios::end);
    size=datei.tellg();
    datei.seekg(0,ios::beg);
    char* temp = new char[size+1];
    datei.read(temp,size);
    temp[size]=0;
    istr.str(temp);
    delete temp;
    }

    So ungefähr sollte das aussehen. Allerdings geht die Übergabe des istringstream Objektes so nicht. Ich weiß nicht, wo da der Fehler liegt. Hab es auch ohne Stern mit Adressoperator versucht, aber das tut es auch nicht.



  • virtuell Realisticer schrieb:

    Windows bietet doch bestimmt auch die Moeglichkeit des Memory Mapped I/O, oder?

    Klar. Allerdings seh ich keinen Weg, dann die normalen Stream-Funktionen zu nützen. Es gibt zwar stringstream, aber irgendein Speicherblock ist noch lange kein std::string.



  • Ringding schrieb:

    Allerdings seh ich keinen Weg, dann die normalen Stream-Funktionen zu nützen.

    Wie wäre es zB mit strstream?
    eigene streambuffer lassen sich auch problemlos schreiben...

    ich verwende hier aber lieber eine noncopy taktik (falls ich die daten nur lesen und nicht ändern will) - da map ich die datei in den speicher und iteriere nur darüber 🙂 und wenn ich werte auslesen will, pack ich sie in einen NoncopyString, der nur aus begin und end iterator besteht und sich somit nur seine position in dem mapping merkt und selber nix kopiert 🙂



  • Ich weiß nicht, was ich von diesem ganzen hin und her halten soll. Die STL ist sicherlich ideal um seinen Sourcecode plattformunabhängig zu halten. Und ich mache soweit wie es geht Gebrauch davon, eigentlich versuche ich 100% die STL zu benutzen.

    Aber wenn ich den Benutzer für eine 30 MB Datei über zwei Minuten warten lassen muß, dann ersetze ich den Flaschenhals durch Betriebssystem-Funktionen die meistens schneller sind ohne groß darüber nachzudenken. In dem Fall denke ich an den Benutzer, wenn ich mit Betriebssystem-Funktionen ihm einen _bedeutenden_ Vorteil verschaffen kann. Der Benutzer wird es einem danken!

    Also, krall dir die Win32-API und schau nach welche Funktionen diese dir bietet. Kapsel das ganze noch in eine eigene Klasse, damit du für einen eventuellen API-Wechsel gerüstet bist und die Anpassung nur an einer Stelle machen mußt. Fertig ist das Thema!



  • Das klingt ja alles sehr interessant, nur leider habe ich keine Ahnung was damit gemeint ist. Mit Windows Programmierung kenne ich mich leider so gut wie gar nicht aus. Und wofür steht STL?


Anmelden zum Antworten