Lees bestandsinhoud in een string in C++

Mogelijk duplicaat:
Wat is het beste manier om een ​​bestand in een std::string in c++ te slurpen?

In scripttalen zoals Perl is het mogelijk om een ​​bestand in één keer in een variabele te lezen.

   open(FILEHANDLE,$file);
    $content=<FILEHANDLE>;

Wat zou de meest efficiënte manier zijn om dit in C++ te doen?


Antwoord 1, autoriteit 100%

Zoals dit:

#include <fstream>
#include <string>
int main(int argc, char** argv)
{
  std::ifstream ifs("myfile.txt");
  std::string content( (std::istreambuf_iterator<char>(ifs) ),
                       (std::istreambuf_iterator<char>()    ) );
  return 0;
}

De verklaring

 std::string content( (std::istreambuf_iterator<char>(ifs) ),
                       (std::istreambuf_iterator<char>()    ) );

kan worden opgesplitst in

std::string content;
content.assign( (std::istreambuf_iterator<char>(ifs) ),
                (std::istreambuf_iterator<char>()    ) );

wat handig is als je gewoon de waarde van een bestaande std::string variabele wilt overschrijven.


Antwoord 2, autoriteit 20%

De meest efficiënte, maar niet de C++-manier zou zijn:

  FILE* f = fopen(filename, "r");
   // Determine file size
   fseek(f, 0, SEEK_END);
   size_t size = ftell(f);
   char* where = new char[size];
   rewind(f);
   fread(where, sizeof(char), size, f);
   delete[] where;

#BEWERKEN – 2

Zojuist ook de variant std::filebufgetest. Het lijkt erop dat het de beste C++-benadering kan worden genoemd, ook al is het niet echt een C++-benadering, maar meer een wrapper. Hoe dan ook, hier is het stukje code dat bijna net zo snel werkt als gewone C.

  std::ifstream file(filename, std::ios::binary);
   std::streambuf* raw_buffer = file.rdbuf();
   char* block = new char[size];
   raw_buffer->sgetn(block, size);
   delete[] block;

Ik heb hier een snelle benchmark gedaan en de resultaten volgen. Er is een test gedaan bij het lezen van een 65536Kbinair bestand met de juiste (std::ios:binaryen rb) modi.

[==========] Running 3 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 4 tests from IO
[ RUN      ] IO.C_Kotti
[       OK ] IO.C_Kotti (78 ms)
[ RUN      ] IO.CPP_Nikko
[       OK ] IO.CPP_Nikko (106 ms)
[ RUN      ] IO.CPP_Beckmann
[       OK ] IO.CPP_Beckmann (1891 ms)
[ RUN      ] IO.CPP_Neil
[       OK ] IO.CPP_Neil (234 ms)
[----------] 4 tests from IO (2309 ms total)
[----------] Global test environment tear-down
[==========] 4 tests from 1 test case ran. (2309 ms total)
[  PASSED  ] 4 tests.

Antwoord 3, autoriteit 6%

Het meest efficiënt is om een ​​buffer van de juiste grootte te maken en het bestand vervolgens in de buffer te lezen.

#include <fstream>
#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.
         * Because char is a POD data type it is not initialized.
         *
         * Then read the whole file into the buffer.
         */
        std::vector<char>       buffer(length);
        file.read(&buffer[0],length);
    }
}

Other episodes