2010-01-26 19 views
13

Tengo el siguiente código y funciona bastante bien (aparte del hecho de que es bastante lento, pero no me importa mucho). No parece intuitivo que esto escribiría todo el contenido del archivo de entrada en el archivo de salida.¿Qué hace ifstream :: rdbuf() en realidad?

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

¿Alguna idea?

+1

Agregaría que las llamadas explícitas a 'close()' no son necesarias. Los destructores harían lo mismo de todos modos. Y eso ahorra algunas líneas. ;) –

Respuesta

12

Sí, está especificado en la norma y en realidad es bastante simple. rdbuf() simplemente devuelve un puntero al objeto subyacente basic_streambuf para el objeto [io]stream dado.

basic_ostream<...> tiene una sobrecarga de operator<< para un puntero a basic_streambuf<...> que escribe el contenido de la basic_streambuf<...>.

+2

¿Pero el operador << no podría escribir solo un fragmento? No es fácil ver que escribirá todo como un solo trozo. Entiendo que es un puntero pero ¿ese puntero contiene la información completa como un solo trozo? Todavía estoy un poco confundido. –

+3

No estoy muy seguro de lo que está manejando con 'un pedazo'? Se especifica para generar el contenido del carácter apuntado a 'streambuf' por carácter hasta que se llega al final del búfer o hay un error que lo genera. El 'streambuf' es una instancia de clase y si almacena su secuencia controlada en la memoria contigua o no, no se especifica y no se puede inferir desde la interfaz. –

+0

Ok, lo hace carácter por carácter hasta que se alcanza el final del búfer. ¿Como sabes eso? No vi eso desde la interfaz provista. –

15

iostream Las clases son solo envoltorios alrededor de búferes de E/S. El iostream en sí no hace mucho ... principalmente, proporciona los operadores de formateo operator>>. El buffer es provisto por un objeto derivado de basic_streambuf, que puede obtener y configurar usando rdbuf().

basic_streambuf es una base abstracta con varias funciones virtuales que se anulan para proporcionar una interfaz uniforme para leer/escribir archivos, cadenas, etc. La función basic_ostream<…>::operator<<(basic_streambuf<…>) se define para seguir leyendo hasta que la fuente de datos subyacente agotado.

iostream es un desastre terrible, sin embargo.

+0

Acepto, y esta es una buena respuesta, pero Charles envió su respuesta primero para que sea el ganador. Sin embargo, ¡elevé tu respuesta! –

Cuestiones relacionadas