2010-10-31 35 views
15

Y at-il de toute façon je peux transférer des données d'un fstream (un fichier) à un stringstream (un flux dans la mémoire)?Copier les données de fstream vers stringstream sans buffer?

Actuellement, j'utilise un tampon, mais cela nécessite le double de la mémoire, car vous devez copier les données dans un tampon, puis copier le tampon dans la chaîne, et jusqu'à ce que vous supprimiez le tampon, les données sont dupliquées dans la mémoire.

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

Est-ce que quelqu'un sait comment je peux écrire un fichier entier à un stringstream sans utiliser un tampon inbetween?

+0

Quel est le point? Essayez-vous d'améliorer le débit? Vous allez probablement devoir abandonner 'fstream' dans ce cas, les iostreams sont SLOW. Essayez-vous de diminuer votre empreinte mémoire? Lire le fichier en morceaux au lieu de tout en même temps pourrait aider avec cela. –

Répondre

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

Ceci est toujours en train de lire le fichier dans le tampon 'ifstream'. –

+0

Il s'agit d'un tampon de moins que le code d'origine. –

+0

@Charles - Néanmoins, je pense que c'est ce qu'il voulait. Il ne voulait pas allouer une nouvelle matrice de caractères. Il voulait lire directement à partir de l'objet fstream vers l'objet stringstream. –

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

La seule façon en utilisant la bibliothèque standard C++ est d'utiliser un ostrstream au lieu de stringstream.

Vous pouvez construire un objet ostrstream avec votre propre tampon char, et il prendra alors possession du tampon (donc plus besoin de copier). Notez toutefois que l'en-tête strstream est obsolète (bien qu'il fasse toujours partie de C++ 03, et très probablement, il sera toujours disponible sur la plupart des implémentations de bibliothèque standard), et vous aurez de gros ennuis si vous oubliez à null-terminer les données fournies à l'ostrstream.Cela s'applique également aux opérateurs de flux, par exemple: ostrstreamobject << some_data << std::ends; (std::ends annule les données).

7

Dans la documentation de ostream, il y a several overloads for operator<<. L'un d'eux prend un streambuf* et lit tout le contenu du streambuffer.

Voici un exemple d'utilisation (compilé et testé):

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