2010-08-18 13 views
5

Beim Versuch, eine Textdatei A auf eine andere Datei B zu kopieren, kann es mehrere Methoden: 1) Byte für Byte 2) Wort für Wort 3) Zeile für ZeileWie kopiere Textdatei in C oder C++?

welches ist effizienter?

+4

Sie haben den Pufferspeicher vergessen. Die C- und C++ - Datenströme sind bereits gepuffert (Größe bezogen auf das Dateisystem des Betriebssystems). Verwenden Sie dies, um Stücke von nahezu optimaler Größe zu kopieren. –

Antwort

18

unter Verwendung von Puffern:

#include <fstream> 

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

    outFile << inFile.rdbuf(); 
} 

Die C++ fstreams werden intern zwischengespeichert. Sie verwenden eine effiziente Puffergröße (trotz was die Leute über die Effizienz von Stream sagen :-). Also kopiere einfach einen Stream-Puffer in einen Stream und hey presto, dass die interne Magie eine effiziente Kopie von einem Stream zum anderen macht.

Aber es ist so viel mehr Spaß, es mit char (char) durch char zu machen.

+0

Ausgezeichnetes. Vielen Dank. – user373215

+0

Iostreams Ruf für Ineffizienz kommt von formatierten I/O; um so rohe Bytes zu schaufeln, ist es ungefähr so ​​gut wie alles andere. –

+0

rdbuf() nicht rdBuf() –

4

Nur "Puffer von Puffer", kopieren Sie Dateien im Binärmodus und lesen/schreiben X Bytes lange Teile. Ich denke, dass die schnellste Lösung ist, die Kopierfunktion der C-Sprache selbst oder den Systemaufruf zu verwenden.

Größter Puffer bietet Ihnen weniger HDD-Suche für Datenoperationen (schnelleres Kopieren), aber mehr RAM-Auslastung.

0

Wenn es gut gemacht wird, ist Byte für Byte effizienter. Natürlich ist das nicht die ganze Geschichte: Es hängt davon ab, wie viele Bytes du gleichzeitig kopierst. Wenn Sie byteweise Byte für Byte kopieren, führen Sie für jedes Byte einen E/A-Aufruf durch und sind langsamer als die String-Bibliotheken. Die meisten Leute raten nur auf eine gute Puffergröße (in der Regel 2048 oder größer, in Vielfachen von 2) und nutzen diese.

+0

Können Sie erklären, welcher Mechanismus dem Raten bei einer guten Puffergröße zugrunde liegt? – user297850

+0

Je nachdem, auf welchem ​​Medium Ihre Textdateien gespeichert sind, verfügen Sie wahrscheinlich über 512-Byte-Sektoren (viele herkömmliche Festplatten) oder 2048-Byte-Sektoren (optische Datenträger, viele Solid-State-Speichergeräte, einige neuere Festplatten) , etc). Um die Arbeit Ihres Laufwerks zu minimieren, möchten Sie ein Vielfaches eines Sektors kopieren.Daher können Sie 2048 Byte zu einem Zeitpunkt mit Operationen kopieren, die an 2048-Byte-Grenzen ausgerichtet sind (oder ein beliebiges Vielfaches von 2K für 2048 ersetzen). – bta

+1

Im Allgemeinen ist es die beste Option, ein Vielfaches der Speicherseitengröße zu verwenden. In Linux glaube ich, dass der Standardwert 4K ist. Der virtuelle Speichermanager ist sehr gut darin, den Rest für Sie zu optimieren, so dass das Lesen/Schreiben einer Seite auf einmal ziemlich schnell sein kann. Größere Puffergrößen sind möglicherweise besser, da weniger Systemaufrufe erforderlich sind (alle Systemaufrufe haben Overhead) und möglicherweise Festplattenpufferung (es gibt jedoch keine Garantie, dass sich Ihre Datei in aufeinanderfolgenden Sektoren auf dem Laufwerk befindet). Es kommt darauf an. – wds

-2

Eigentlich musste ich selbst einmal dasselbe machen, also habe ich es mit verschiedenen Größen gemessen. Was ich fand, war, dass bei einer großen Datei die benötigte Zeit fast ausschließlich davon abhing, wie viele I/O's ich ausführte (unabhängig von ihrer Größe).

Sie sollten also möglichst wenige I/O's machen. Vorzugsweise zwei (eins zum Lesen und das andere zum Schreiben).

0

Wenn Sie Wort für Wort oder Zeile für Zeile vorgehen, können Sie die ursprüngliche Datei kaum rekonstruieren, da es viele Formen von Zeilenumbrüchen (\ r, \ n, \ r \ n) und Leerzeichen (\ p, \ f, 0x32) eingebettet in Textdateien, die Sie riskieren, auf diese Weise zu verlieren.

Der effektivste Weg zum Kopieren von Dateien ist die Verwendung von Byte-Puffern. Je größer der Puffer ist, desto effizienter ist das Kopieren, solange Ihre Puffergröße nicht größer ist als die interne Puffergröße der Festplatte (heute meist ~ 8 MB).

0

Verwenden Sie die C++ - Iostreams und die STL. Unten ist ein Beispiel:

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

Hinweis: dies nicht in allen Situationen geeignet sein könnte. Verwenden/passen Sie dies entsprechend Ihren spezifischen Anforderungen an (z. B. normale oder humong Dateien).