2010-10-31 15 views
15

¿De todos modos puedo transferir datos de fstream (un archivo) a stringstream (una secuencia en la memoria)?¿Copiar datos de fstream a stringstream sin buffer?

Actualmente, estoy usando un búfer, pero esto requiere el doble de memoria, porque necesita copiar los datos en un búfer, luego copie el búfer en el flujo de cadenas y hasta que elimine el búfer, los datos se duplican en la memoria

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;` 

¿Alguien sabe cómo puedo escribir un archivo completo en una secuencia de cadenas sin usar un buffer intermedio?

+0

Cuál es el punto? ¿Estás tratando de mejorar el rendimiento? Es probable que necesites abandonar 'fstream' en ese caso, iostreams son LENTOS. ¿Estás tratando de disminuir tu huella de memoria? Leer el archivo en trozos en lugar de todos a la vez podría ayudar con eso. –

Respuesta

25
// 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)); 
+0

Esto sigue leyendo el archivo en el búfer 'ifstream'. –

+0

Es un buffer menos que el código original. –

+0

@Charles - No obstante, creo que esto es lo que pretendía. No quería asignar una nueva matriz de caracteres. Quería leer directamente del objeto fstream al objeto de cadena de caracteres. –

20
ifstream f(fName); 
stringstream s; 
if (f) { 
    s << f.rdbuf();  
    f.close(); 
} 
1

La única forma de usar el ++ biblioteca estándar C es utilizar un ostrstream en lugar de stringstream.

Puede construir un objeto ostrstream con su propio búfer char, y se hará cargo del búfer (entonces no se necesita más copia).

Nota, sin embargo, que el encabezado strstream está en desuso (aunque sigue siendo parte de C++ 03, y muy probablemente siempre estará disponible en la mayoría de las implementaciones de bibliotecas estándar), y te meterás en grandes problemas si lo olvidas para anular la terminación de los datos suministrados al ostrstream. Esto también se aplica a los operadores de flujo, por ejemplo: ostrstreamobject << some_data << std::ends; (std::ends nullterminates data).

7

En la documentación para ostream, hay several overloads for operator<<. Uno de ellos toma un streambuf* y lee todos los contenidos del streambuffer.

Aquí es un uso de la muestra (compilado y probado):

#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); 
} 
Cuestiones relacionadas