Frage

Um die Leistung Lesen aus einer Datei zu verbessern, ich versuche, den gesamten Inhalt eines großen (mehrere MB) Datei in dem Speicher zu lesen und dann eine istringstream verwenden, um auf die Informationen zugreifen.

Meine Frage ist, was der beste Weg ist, diese Informationen und „Import es“ in den String-Stream zu lesen? Ein Problem bei diesem Ansatz (siehe unten) besteht darin, dass bei der Erstellung des String der Puffer-Stream wird kopiert, und die Speichernutzung verdoppelt.

#include <fstream>
#include <sstream>

using namespace std;

int main() {
  ifstream is;
  is.open (sFilename.c_str(), ios::binary );

  // get length of file:
  is.seekg (0, std::ios::end);
  long length = is.tellg();
  is.seekg (0, std::ios::beg);

  // allocate memory:
  char *buffer = new char [length];

  // read data as a block:
  is.read (buffer,length);

  // create string stream of memory contents
  // NOTE: this ends up copying the buffer!!!
  istringstream iss( string( buffer ) );

  // delete temporary buffer
  delete [] buffer;

  // close filestream
  is.close();

  /* ==================================
   * Use iss to access data
   */

}
War es hilfreich?

Lösung

std::ifstream hat eine Methode rdbuf(), die einen Zeiger auf eine filebuf zurückgibt. Sie können "Push" dieses filebuf in Ihre stringstream dann:

#include <fstream>
#include <sstream>

int main()
{
    std::ifstream file( "myFile" );

    if ( file )
    {
        std::stringstream buffer;

        buffer << file.rdbuf();

        file.close();

        // operations on the buffer...
    }
}

EDIT: Wie Martin York in den Kommentaren bemerkt, ist dies nicht die schnellste Lösung, da die stringstream der operator<< den filebuf Charakter sein könnte von Zeichen wird gelesen. Vielleicht möchten Sie seine Antwort überprüfen, wo er die ifstream Methode des read verwendet wie Sie verwendet, und stellen Sie dann den stringstream Puffer auf die zuvor zugewiesenen Speicher zeigen.

Andere Tipps

OK. Ich sage nicht, dies schneller sein wird als aus der Datei
Lesen

Aber das ist ein Verfahren, bei dem man den Puffer einmal erstellen und nachdem die Daten in den Puffer es gelesen wird, verwenden, um direkt als Quelle für string.

NB. Es ist erwähnenswert, dass die std :: ifstream gepuffert. Er liest Daten aus der Datei in (relativ großen) Stücken schneiden. Stream-Operationen werden durchgeführt, gegen die Puffer nur für eine andere Lese in die Datei zurückkehrt, wenn mehr Daten benötigt werden. Also, bevor alle Daten in den Speicher saugen bitte überprüfen, ob dies ist ein Flaschenhals.

#include <fstream>
#include <sstream>
#include <vector>

int main()
{
    std::ifstream       file("Plop");
    if (file)
    {
        /*
         * Get the size of the file
         */
        file.seekg(0,std::ios::end);
        std::streampos          length = file.tellg();
        file.seekg(0,std::ios::beg);

        /*
         * Use a vector as the buffer.
         * It is exception safe and will be tidied up correctly.
         * This constructor creates a buffer of the correct length.
         *
         * Then read the whole file into the buffer.
         */
        std::vector<char>       buffer(length);
        file.read(&buffer[0],length);

        /*
         * Create your string stream.
         * Get the stringbuffer from the stream and set the vector as it source.
         */
        std::stringstream       localStream;
        localStream.rdbuf()->pubsetbuf(&buffer[0],length);

        /*
         * Note the buffer is NOT copied, if it goes out of scope
         * the stream will be reading from released memory.
         */
    }
}

Dies scheint wie vorzeitige Optimierung zu mir. Wie viel Arbeit wird in der Verarbeitung durchgeführt wird. Unter der Annahme einen modernish Desktop / Server, und nicht ein eingebettetes System, ein paar MB Daten während intialization Kopieren ist ziemlich billig, vor allem im Vergleich zum Lesen der Datei aus der Festplatte an erster Stelle. Ich würde mit dem, was Sie haben, um das System messen, wenn es abgeschlossen ist, und die entscheiden, ob die potenziellen Performance-Gewinne wären es wert. Natürlich, wenn der Speicher knapp ist, ist dies in einer inneren Schleife, oder ein Programm, das oft (wie einmal pro Sekunde) aufgerufen wird, ändert sich das die Waage.

Eine andere Sache im Auge zu behalten ist, dass Datei-I / O wird immer der langsamste Betrieb sein wird. Luc Touraille Lösung ist richtig, aber es gibt auch andere Optionen. die gesamte Datei in den Speicher liest, wird auf einmal viel schneller als getrennte liest.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top