Скопировать данные из потока в строку без буфера? - PullRequest
19 голосов
/ 31 октября 2010

Есть ли способ передать данные из fstream (файла) в stringstream (поток в памяти)?

В настоящее время я использую буфер, но для этого требуетсяУдвойте память, потому что вам нужно скопировать данные в буфер, затем скопировать буфер в поток строк, и пока вы не удалите буфер, данные дублируются в памяти.

std::fstream fWrite(fName,std::ios::binary | std::ios::in | std::ios::out);  
    fWrite.seekg(0,std::ios::end); //Seek to the end  
    int fLen = fWrite.tellg(); //Get length of file  
    fWrite.seekg(0,std::ios::beg); //Seek back to beginning  
    char* fileBuffer = new char[fLen];  
    fWrite.read(fileBuffer,fLen);  
    Write(fileBuffer,fLen); //This writes the buffer to the stringstream  
    delete fileBuffer;`

Кто-нибудь знаетКак я могу записать весь файл в поток строк без использования промежуточного буфера?

Ответы [ 4 ]

25 голосов
/ 31 октября 2010
// need to include <algorithm> and <iterator>, and of course <fstream> and <sstream>
ifstream fin("input.txt");
ostringstream sout;
copy(istreambuf_iterator<char>(fin),
     istreambuf_iterator<char>(),
     ostreambuf_iterator<char>(sout));
24 голосов
/ 31 октября 2010
 ifstream f(fName);
 stringstream s;
 if (f) {
     s << f.rdbuf();    
     f.close();
 }
6 голосов
/ 31 октября 2010

В документации для ostream есть несколько перегрузок для operator<<.Один из них берет streambuf* и читает все содержимое потокового буфера.

Вот пример использования (скомпилированный и протестированный):

#include <exception>
#include <iostream>
#include <fstream>
#include <sstream>

int main ( int, char ** )
try
{
        // Will hold file contents.
    std::stringstream contents;

        // Open the file for the shortest time possible.
    { std::ifstream file("/path/to/file", std::ios::binary);

            // Make sure we have something to read.
        if ( !file.is_open() ) {
            throw (std::exception("Could not open file."));
        }

            // Copy contents "as efficiently as possible".
        contents << file.rdbuf();
    }

        // Do something "useful" with the file contents.
    std::cout << contents.rdbuf();
}
catch ( const std::exception& error )
{
    std::cerr << error.what() << std::endl;
    return (EXIT_FAILURE);
}
1 голос
/ 31 октября 2010

Единственный способ использовать стандартную библиотеку C ++ - это использовать ostrstream вместо stringstream.

. Вы можете создать объект ostrstream с вашим собственным буфером символов, и он станет владельцемзатем буфер (поэтому больше копирование не требуется).

Обратите внимание, однако, что заголовок strstream устарел (хотя он все еще является частью C ++ 03 и, скорее всего, он всегда будет доступен набольшинство реализаций стандартной библиотеки), и вы столкнетесь с большими проблемами, если забудете завершить нулем данные, предоставленные ostrstream. Это также относится к операторам потока, например: ostrstreamobject << some_data << std::ends; (std::ends null определяет данные).

...