2010-01-26 15 views
13

J'ai le code suivant et ça marche plutôt bien (à part le fait que c'est assez lent, mais je m'en fous de ça). Il ne semble pas intuitif que cela écrirait tout le contenu de l'infile à la sortie.Que fait réellement ifstream :: rdbuf()?

// Returns 1 if failed and 0 if successful 
int WriteFileContentsToNewFile(string inFilename, string outFilename) 
{ 
    ifstream infile(inFilename.c_str(), ios::binary); 
    ofstream outfile(outFilename.c_str(), ios::binary); 

    if(infile.is_open() && outfile.is_open() && infile.good() && outfile.good()) 
    { 
     outfile << infile.rdbuf(); 

     outfile.close(); 
     infile.close(); 
    } 
    else 
     return 1; 

    return 0; 
} 

Un aperçu?

+1

J'ajouterais que les appels explicites à 'close()' ne sont pas nécessaires. Les destructeurs feraient de même de toute façon. Et cela sauve quelques lignes. ;) –

Répondre

12

Oui, c'est spécifié dans la norme et c'est en fait assez simple. rdbuf() renvoie juste un pointeur vers l'objet basic_streambuf sous-jacent pour l'objet [io]stream donné.

basic_ostream<...> a une surcharge pour operator<< un pointeur vers basic_streambuf<...> qui écrit le contenu du basic_streambuf<...>.

+2

Mais l'opérateur << n'écrirait-il qu'un morceau? Ce n'est pas facile de voir que tout sera écrit en un seul morceau. Je comprends que c'est un pointeur, mais ce pointeur contient-il toutes les données en un morceau? Je suis encore un peu confus. –

+3

Je ne suis pas sûr de ce que vous conduisez avec «un morceau»? Il est spécifié de sortir le contenu du caractère pointé vers streambuf par caractère jusqu'à ce que la fin du tampon soit atteinte ou qu'une erreur se produise. Le 'streambuf' est une instance de classe et s'il stocke sa séquence contrôlée dans la mémoire contiguë ou non n'est pas spécifié et ne peut pas être déduit de l'interface. –

+0

Ok, il le fait caractère par caractère jusqu'à ce que la fin du tampon soit atteinte. Comment sais-tu ça? Je n'ai pas vu cela depuis l'interface fournie. –

15

iostream Les classes ne sont que des wrappers autour des tampons d'E/S. Le iostream lui-même ne fait pas beaucoup ... principalement, il fournit les opérateurs de formatage operator>>. Le tampon est fourni par un objet dérivé de basic_streambuf, que vous pouvez obtenir et définir à l'aide de rdbuf().

basic_streambuf est une base abstraite avec un certain nombre de fonctions virtuelles qui sont remplacées pour fournir une interface uniforme pour la lecture/écriture des fichiers, des chaînes, etc. La fonction basic_ostream<…>::operator<<(basic_streambuf<…>) est définie pour maintenir la lecture à travers la mémoire tampon jusqu'à ce que la source de données sous-jacente est épuisé.

iostream est un gâchis terrible, cependant.

+0

Je suis d'accord, et c'est une bonne réponse mais Charles a soumis sa réponse en premier, donc il est le gagnant. J'ai voté votre réponse si! –