2010-01-26 14 views
13

Ho il seguente codice e funziona piuttosto bene (a parte il fatto che è piuttosto lento, ma non mi interessa molto di questo). Non sembra intuitivo che questo scriva l'intero contenuto del file in uscita.Che cosa fa effettivamente 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; 
} 

Qualche idea?

+1

Vorrei aggiungere che le chiamate esplicite a 'close()' non sono necessarie. I distruttori farebbero lo stesso comunque. E questo risparmia alcune linee. ;) –

risposta

12

Sì, è specificato nello standard ed è in realtà abbastanza semplice. rdbuf() restituisce semplicemente un puntatore all'oggetto basic_streambuf sottostante per l'oggetto [io]stream specificato.

basic_ostream<...> ha un sovraccarico per operator<< per un puntatore a basic_streambuf<...> che scrive il contenuto del basic_streambuf<...>.

+2

Ma l'operatore non dovrebbe << solo scrivere un chunk? Non è facile vedere che scriverà tutto come un unico blocco. Capisco che sia un puntatore ad esso, ma quel puntatore contiene l'intero dato come un unico blocco? Sono ancora un po 'confuso. –

+3

Non sono abbastanza sicuro di cosa stai guidando con "un pezzo"? Viene specificato per l'output del carattere puntato al carattere 'streambuf' per carattere fino a quando non viene raggiunta la fine del buffer o c'è un errore che lo emette. 'Streambuf' è un'istanza di classe e se memorizza la sua sequenza controllata nella memoria contigua o meno non è specificata e non può essere dedotta dall'interfaccia. –

+0

Ok, lo fa carattere per carattere fino al raggiungimento della fine del buffer. Come fai a saperlo? Non l'ho visto dall'interfaccia fornita. –

15

iostream classi sono solo wrapper attorno ai buffer I/O. Lo stesso iostream non fa molto ... principalmente, fornisce gli operatori di formattazione operator>>. Il buffer è fornito da un oggetto derivato da basic_streambuf, che è possibile ottenere e impostare utilizzando rdbuf().

basic_streambuf è una base astratta con un numero di funzioni virtuali che sono forzate a fornire un'interfaccia uniforme per la lettura/scrittura di file, stringhe, ecc La funzione basic_ostream<…>::operator<<(basic_streambuf<…>) è definita per mantenere lettura attraverso il buffer finché dei dati sottostante è esausto.

iostream è un pasticcio terribile, però.

+0

Sono d'accordo, e questa è una buona risposta, ma Charles ha presentato la sua risposta prima, quindi è il vincitore. Ho votato la tua risposta! –

Problemi correlati