2010-08-18 41 views
5

Al intentar copiar un archivo de texto de A a otro archivo B, puede tener varios métodos: 1) byte a byte 2) palabra por palabra 3) línea por líneaCómo copiar archivos de texto en C o C++?

cuál es más eficiente?

+4

Olvidó el búfer por el búfer. Las secuencias C y C++ ya están almacenadas en el búfer (tamaño relacionado con el sistema de archivos del sistema operativo). Use esto para copiar trozos de tamaño casi óptimo. –

Respuesta

18

usando tampones:

#include <fstream> 

int main() 
{ 
    std::ifstream inFile("In.txt"); 
    std::ofstream outFile("Out.txt"); 

    outFile << inFile.rdbuf(); 
} 

fstreams El C++ se almacenan internamente. Usan un tamaño de búfer eficiente (a pesar de lo que dice la gente sobre la eficiencia de la transmisión :-). Así que solo copie un búfer de secuencia en una secuencia y listo, la magia interna hará una copia eficiente de una secuencia a la otra.

Pero aprender a hacerlo char por char usando std :: copy() es mucho más divertido.

+0

Excelente. Gracias. – user373215

+0

La reputación de ineficiencia de Iostreams proviene de E/S formateada; para palear bytes crudos como este, es casi tan bueno como podría ser cualquier cosa. –

+0

rdbuf() no rdBuf() –

4

Simplemente "buffer by buffer", copie archivos en modo binario y lea/escriba X bytes de partes largas. Creo que la solución más rápida es simplemente usar la función de copia del lenguaje C o la llamada al sistema.

El búfer más grande le proporcionará menos HDD para operaciones de datos (copia más rápida) pero más uso de RAM.

0

Si se hace bien, Byte byte es más eficiente. Por supuesto, esa no es toda la historia: depende de la cantidad de bytes que copia a la vez. Si literalmente copia el byte por byte, hará una llamada de E/S por cada byte y terminará siendo más lento que las bibliotecas de cadenas. La mayoría de las personas simplemente adivinan un buen tamaño de búfer (generalmente 2048 o más, en múltiplos de 2) y lo usan.

+0

¿Puede explicar cuál es el mecanismo subyacente a la adivinación de un buen tamaño de búfer? – user297850

+0

Según el tipo de medio en que almacene sus archivos de texto, probablemente tenga sectores de 512 bytes (muchos discos duros tradicionales) o sectores de 2048 bytes (discos ópticos, muchos dispositivos de memoria de estado sólido, algunos discos duros más nuevos) , etc.) Para minimizar el trabajo que su disco tiene que hacer, desea copiar en múltiplos de un sector.Por lo tanto, puede copiar 2048 bytes a la vez, con operaciones alineadas a límites de 2048 bytes (o, sustituir cualquier múltiplo de 2K por 2048). – bta

+1

Generalmente, la mejor opción es usar un múltiplo del tamaño de página de la memoria. En Linux, creo que el valor predeterminado es 4K. El administrador de memoria virtual es muy bueno para optimizar el resto, por lo que leer/escribir una página a la vez puede ser bastante rápido. Usar tamaños de búfer más grandes podría ser mejor debido a menos llamadas de sistema necesarias (todas las llamadas de sistema tienen sobrecarga) y quizás búfer de disco duro (no obstante, no hay garantía de que su archivo estará en sectores consecutivos en la unidad). Depende. – wds

-2

En realidad tuve que hacer lo mismo una vez, así que lo sincronicé con varios tamaños. Lo que encontré fue que, dado un archivo grande, el tiempo empleado era casi en su totalidad una función de la cantidad de E/S que realicé (independientemente de su tamaño).

Por lo tanto, su mejor opción es hacer la menor cantidad posible de E/S. Preferiblemente dos (uno para leer y el otro para escribir).

0

Si hace palabra por palabra o línea por línea, difícilmente podrá reconstruir el archivo original, ya que hay muchas formas de saltos de línea (\ r, \ n, \ r \ n) y espacios (\ p, \ f, 0x32) incrustado en archivos de texto que corre el riesgo de perder de esta manera.

La manera más eficiente de copiar archivos es utilizar byte-buffers. Cuanto mayor sea el búfer, más eficiente será la copia, siempre y cuando el tamaño del búfer no sea mayor que el tamaño del búfer interno del disco duro (hoy en su mayoría ~ 8mb).

0

Intente utilizar C++ iostreams y STL. A continuación se muestra un ejemplo:

ifstream infile("to_copy.txt"); 
if (infile) 
{ 
    istreambuf_iterator<char> ifit(infile); 
    ofstream outfile("the_copy.txt"); 
    ostreambuf_iterator<char> ofit(outfile); 
    if (outfile) 
    { 
     copy(ifit, istreambuf_iterator<char>(), ofit); 
     outfile.close(); 
    } 
    else 
    { 
     cerr << "Could not open output file" << "\n"; 
    } 
    infile.close(); 
} 
else 
{ 
    cerr << "Could not open input file" << "\n"; 
} 

Nota: esto podría no ser adecuado en todas las situaciones. Utilice/personalice esto según sus requisitos específicos (por ejemplo, archivos ordinarios o enormes).

Cuestiones relacionadas