2010-01-26 4 views
13

Ich habe den folgenden Code und es funktioniert ziemlich gut (abgesehen von der Tatsache, dass es ziemlich langsam ist, aber das ist mir egal). Es scheint nicht intuitiv, dass dies den gesamten Inhalt der Infile in das Outfile schreiben würde.Was macht ifstream :: rdbuf() eigentlich?

// 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; 
} 

Irgendein Einblick?

+1

Ich würde hinzufügen, dass explizite Aufrufe von 'close()' nicht benötigt werden. Destruktoren würden das gleiche tun. Und das spart einige Zeilen. ;) –

Antwort

12

Ja, es ist in der Norm angegeben und es ist eigentlich ziemlich einfach. rdbuf() gibt nur einen Zeiger auf das zugrunde liegende Objekt basic_streambuf für das angegebene Objekt [io]stream zurück.

basic_ostream<...> hat eine Überlast für operator<< für einen Zeiger auf basic_streambuf<...>, die aus dem Inhalt des basic_streambuf<...> schreibt.

+2

Aber würde nicht Betreiber << nur einen Brocken schreiben? Es ist nicht leicht zu sehen, dass es das ganze Ding als ein Stück aufschreiben wird. Ich verstehe, dass es ein Zeiger darauf ist, aber enthält dieser Zeiger die gesamten Daten als ein Stück? Ich bin immer noch ein wenig verwirrt. –

+3

Ich bin mir nicht ganz sicher, was Sie mit "einem Stück" fahren? Es wird angegeben, dass der Inhalt von streambuf Zeichen für Zeichen ausgegeben wird, bis das Ende des Puffers erreicht ist oder ein Fehler bei der Ausgabe auftritt. Der 'streambuf' ist eine Klasseninstanz und es wird nicht angegeben, ob er seine gesteuerte Sequenz im zusammenhängenden Speicher speichert oder nicht, und kann nicht von der Schnittstelle abgeleitet werden. –

+0

Ok, es tut Zeichen für Zeichen, bis das Ende des Puffers erreicht ist. Wie kannst du das Wissen? Ich habe das von der bereitgestellten Schnittstelle nicht gesehen. –

15

iostream Klassen sind nur Wrapper um I/O-Puffer. Die iostream selbst tut nicht viel ... vor allem bietet es die operator>> Formatierungsoperatoren. Der Puffer wird von einem Objekt bereitgestellt, das von basic_streambuf abgeleitet ist und über rdbuf() abgerufen und festgelegt werden kann.

basic_streambuf eine abstrakte Basis mit einer Reihe von virtuellen Funktionen, die eine einheitliche Schnittstelle zum Lesen/Schreiben von Dateien, Zeichenkette zu schaffen, außer Kraft gesetzt sind, usw. Die Funktion basic_ostream<…>::operator<<(basic_streambuf<…>) ist definiert durch den Puffer zu lesen Sie, bis die Quelle zugrunde liegenden Daten erschöpft.

iostream ist eine schreckliche Sauerei, obwohl.

+0

Ich stimme zu, und das ist eine gute Antwort, aber Charles reichte seine Antwort zuerst ein, damit er der Gewinner ist. Ich habe deine Antwort jedoch abgestimmt! –