2010-01-26 48 views
13

Mam następujący kod i działa całkiem dobrze (poza tym, że jest dość powolny, ale nie przejmuję się tym). Nie wydaje się intuicyjne, że zapisałoby to całą zawartość pliku do pliku wyjściowego.Co właściwie robi funkcja if :: 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; 
} 

Dowolny wgląd?

+1

Dodam, że jawne wywołania funkcji 'close()' nie są potrzebne. Destruktorzy i tak by postąpili tak samo. A to oszczędza trochę linii. ;) –

Odpowiedz

12

Tak, jest określona w standardzie i jest całkiem prosta. rdbuf() właśnie zwraca wskaźnik do bazowego obiektu basic_streambuf dla podanego obiektu .

basic_ostream<...> ma przeciążenia dla operator<< dla wskaźnika do basic_streambuf<...> który wypisze zawartość basic_streambuf<...>.

+2

Ale czy operator nie << po prostu wypisze jedną porcję? Nie jest łatwo zauważyć, że całość zostanie napisana jako jedna porcja. Rozumiem, że jest to wskaźnik, ale czy ten wskaźnik zawiera całe dane jako jedną porcję? Nadal jestem nieco zdezorientowany. –

+3

Nie jestem do końca pewny, do czego zmierzasz z "jednym kawałkiem"? Jest określony, aby wyprowadzać zawartość wskazywanego znaku 'streambuf' po znaku, aż do osiągnięcia końca bufora lub wystąpi błąd wyprowadzający go. 'Streambuf' jest instancją klasy i nie określa, czy zapisuje kontrolowaną sekwencję w ciągłej pamięci, czy nie, i nie można jej wywnioskować z interfejsu. –

+0

OK, robi to znak po znaku, dopóki nie zostanie osiągnięty koniec bufora. Skąd to wiesz? Nie widziałem tego z dostarczonego interfejsu. –

15

iostream klasy są tylko owijkami wokół buforów wejścia/wyjścia. Samo iostream nie robi wiele ... głównie, zapewnia operatorom formatującym operator>>. Bufor jest dostarczany przez obiekt pochodzący z basic_streambuf, który można uzyskać i ustawić przy użyciu rdbuf().

basic_streambuf jest abstrakcyjną podstawa z wielu funkcji wirtualnych, które są zastępowane w celu zapewnienia jednolitego interfejsu dla odczytu/zapisu plików, sznurki, itd. Funkcja basic_ostream<…>::operator<<(basic_streambuf<…>) definiuje się zachować czytania przez bufor aż źródle danych jest wyczerpany.

iostream to straszny bałagan.

+0

Zgadzam się, i to jest dobra odpowiedź, ale Charles przedstawił swoją odpowiedź jako pierwszy, więc jest zwycięzcą. Wciąż głosowałem na twoją odpowiedź! –