PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : C: Effizientes Kopieren von Dateien?



nobody0
29-11-2004, 11:20
Wie kopiert man Dateien möglichst schnell? :confused:

Ich benutze bisher diese Schleife:



while ((i_c = fgetc (fb)) != EOF) // copy fb to fa
fputc (i_c, fa);


aber bei einer 100 MB-Datei ist cp gut 5 mal schneller (gut 100 MB/s), auch wenn die Dateien alle im RAM gecacht sind.

wraith
29-11-2004, 11:49
Mit fread und fwrite.
Dann eine angemessene Buffergröße, erster Anhaltspunkt kann zb. BUFSIZ aus stdio.h sein.Größere Werte sind wahrscheinlich besser.
Ein wenig testen.

nobody0
29-11-2004, 13:31
Aha, danke.
Dann fehlt noch ein Beispiel mit einem entsprechenden Algorithmus, für das Dateiende (Geldwechsel-Algorithmus) :rolleyes:

nobody0
29-11-2004, 23:31
Also ich habe mal im Sourcecode von cp in den coreutils nachgesehen: Dort wird open/close und read/write verwendet und über den Rückgabewert von read braucht man keinen extra-Algorithmus sonder nur eine Schleife.

wraith
30-11-2004, 20:04
Also ich habe mal im Sourcecode von cp in den coreutils nachgesehen: Dort wird open/close und read/write verwendet und über den Rückgabewert von read braucht man keinen extra-Algorithmus sonder nur eine Schleife.
Also Fehlerabfragen (feof/ferror) würde ich noch nicht als Algorithmus bezeichnen.
Auch mit fread/fwrite ist eine 'nur' eine Schleife mit 2,3 Fehlerabfragen.

Der Vorteil ist, daß es einfacher ist eine performante File-Copy Funktion mit fread/fwrite zu schreiben, da man sich nicht dem internen Buffering auseinandersetzen muß.

nobody0
30-11-2004, 22:25
Ja, das meine ich.

Mein erster Plan war blockweise auszulesen bis zum Ende; dort schlägt der leztzte Zugiff meist fehl (wobei auch nicht gelesen werden kann), weil die Dateilänge meist nicht blocksize * n ist. Deshalb müsste der Rest mit blocksize/2, dann blocksize/4 usw. gelesen werden; also der Geldwechsel-Algorithmus verwendet werden.

Das ist aber unnötig, weil read/write auch unvollständige Blöcke korrekt verarbeiten.

wraith
30-11-2004, 22:35
Mein erster Plan war blockweise auszulesen bis zum Ende; dort schlägt der leztzte Zugiff meist fehl (wobei auch nicht gelesen werden kann), weil die Dateilänge meist nicht blocksize * n ist. Deshalb müsste der Rest mit blocksize/2, dann blocksize/4 usw. gelesen werden; also der Geldwechsel-Algorithmus verwendet werden.

Klingt doch arg kompliziert, warum nicht einfach so


while(1)
{
if(!(sread = fread(buffer,1,sizeof buffer,fin)) && feof(fin))
{
/* EOF erreicht */
break;
}

if(ferror(fin))
{
/* Fehler beim Lesen, Fehlerbehandlung */
}

if((swrite = fwrite(buffer,1,sread,fout)) != sread)
{
/* Fehler beim Schreiben, Fehlerbehandlung */
}
}

nobody0
01-12-2004, 09:04
Ja, das meine ich doch.

Zu Anfang der Überlegungen wußte ich nur nicht, dass es so einfach geht, weil das Komplizierte schon von read/write gemacht wird.