die Rückgabewerte prüfen fread und fwrite
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]){
if(argc != 3){
printf("Usage: ./copy filename newfile\n");
exit(1);
}
int bytes;
long file_size, file_copied_size;
FILE *file_to_copy, *new_file;
if((file_to_copy = fopen(argv[1], "rb")) == NULL){
printf("File cannot be opened - read\n");
exit(1);
}
if((new_file = fopen(argv[2], "wb")) == NULL){
printf("File cannot be opened - write\n");
exit(1);
}
fseek(file_to_copy, 0, SEEK_END);
file_size = ftell(file_to_copy);
rewind(file_to_copy);
char *buffer = malloc(1024 * 1024); /* Imposto un buffer di 1MB per maggiore efficienza */
if(!buffer){
printf("Errore allocazione memoria\n");
fclose(file_to_copy);
fclose(new_file);
exit(1);
}
/* In questo modo copio file grandi 1MB alla volta così il trasferimento è più veloce ed efficiente inoltre fread() ritorna 0 quando c'è un errore o quando incontra EOF */
//while ((bytes=fread(buffer, 1, sizeof(buffer), file_to_copy)) > 0){
while (!feof(file_to_copy)){
bytes = fread(buffer, 1, sizeof(buffer), file_to_copy);
fwrite(buffer, 1, bytes, new_file);
if(ferror(new_file)){
perror("Errore scrittura"); /* perror printa anche l'errore che ferror ha incontrato */
fclose(file_to_copy);
fclose(new_file);
exit(1);
}
}
fseek(new_file, 0, SEEK_END);
file_copied_size = ftell(new_file);
rewind(new_file);
if(file_size != file_copied_size){
printf("Il file %s non è stato copiato correttamente\n", argv[2]);
}
else{
printf("File successfully copied :)\n");
}
fclose(file_to_copy);
fclose(new_file);
free(buffer);
return EXIT_SUCCESS;
}
EDIT: ich habe aktualisiert, der code
ich habe einige Zweifel:
1) muss ich überprüfen den Rückgabewert von fread, weil - zum Beispiel - wenn Byte 0 werden aufgrund eines Fehlers, 0 geschrieben wird in die Datei kopiert.
Aber meine Frage ist: wie ist es zu tun? Da fread kann 0 zurück, sondern können sich auch wieder einen kurzen Wert ....
2) wie können, Lesen Sie gehen Sie durch die Datei? Wenn ich kopieren Sie eine 5 MB-Datei, wie kann fread bewegen sich von 1 MB in 1-MB-ohne etwas sagen zu Ihr "hey Sie haben, um Ihren offset von 1MB nach der 1MB hast du einfach nur kopiert"?
3) warum nicht, deaktivieren Sie den Puffer nach jedem Gebrauch? Ich meine so etwas wie:
while (!feof(file_to_copy)){
bytes = fread(buffer, 1, sizeof(buffer), file_to_copy);
fwrite(buffer, 1, bytes, new_file);
memset(buffer, 0, sizeof(buffer));
}
size_t
statt eines intstack-überlauf 🙁
Ich in der Regel verwenden Sie fread(buffer, Dateigröße, 1, file_to_copy), und überprüfen Sie die Rückgabe von fread, ob gleich 1
InformationsquelleAutor polslinux | 2012-06-15
Du musst angemeldet sein, um einen Kommentar abzugeben.
In der Regel, Sie nicht möchten Sie versuchen, kopieren Sie eine komplette Datei in eine einzelne lese/schreib-Zyklus. Dies hat (unter anderem) eine ziemlich große chance, Ihr Speicherreservierung fehlschlagen, oder schrecklich ineffizient, wenn Sie am Ende der Zuweisung/Verwendung einigen virtuellen Speicher.
Stattdessen möchten Sie in der Regel reserviert einen Puffer von angemessener Größe (sagen wir, ein megabyte oder zwei), dann tun die das kopieren in einer Schleife, so etwas wie:
Können Sie natürlich auch überprüfen Sie den Rückgabewert von
fwrite
und (zum Beispiel) verlassen der Schleife, wenn Sie nicht schreiben Sie den Betrag, den Sie angefordert. Dies ist besonders wichtig, wenn, zum Beispiel, verschieben Sie eine Datei statt nur kopieren-Sie wollen nur das original entfernen, wenn Sie sicher sind, die Kopie ist gelungen.aber warum wollen Sie überprüfen, bytes > 0 ? Tut fread gibt 0 zurück, wenn es zu erreichen der EOF? Und auch, warum Sie nicht "klar", die Puffer vor der Wiederverwendung?
gibt die Anzahl der Elemente, die erfolgreich gelesen, so schreiben wir diese Zahl wieder aus. Ja, wenn Sie es nicht Lesen können, alles, was es gibt 0 zurück (unabhängig davon, ob das Ende der Datei oder etwas anderes, wie ein disk-Fehler). Sie brauchen nicht, um den Puffer klar, denn das einzige Teil, das wir verwenden, ist der Teil, der
fread
gerade geschrieben hatte.Ah ok, habe ich verstanden...aber was ich nicht unserstand ist: wenn wir reservieren, 1 MB für die buffer und wir schreiben 1MB in den Puffer, das nächste mal, wir schreiben in es - zum Beispiel - 400 KB gibt es weitere 600 KB geschrieben wurden, und schmutzig sind...oder die malloced Puffer funktioniert nicht wie array??
Schauen Sie genau-wir halten den Rückgabewert von
fread
imbytes
. Wenn wir rufenfwrite
passieren wirbytes
(d.h., die Menge, die gelesen wurde) als Menge zu schreiben. Also, wenn wir Lesen einen gesamten Puffer voll ist, das ist, was wir schreiben-wenn wir aber nur Lesen eine partielle Puffer, das ist, wie viel wir schreiben.InformationsquelleAutor Jerry Coffin
Rufen Sie ferror() um den Fehler zu überprüfen status eines I/O-stream-wenn der fread/fwrite kopiert nicht die Anzahl der Zeichen, die Sie erwarten
while ((bytes=fread(buffer, 1, sizeof(buffer), file_to_copy)) > 0){ fwrite(buffer, 1, bytes, new_file); if(ferror(new_file){ printf("Errore scrittura\n"); fclose(file_to_copy); fclose(new_file); exit(1); } }
ja, siehe auch perror() druckt die aktuelle system-Fehlermeldung, ferror() gefunden
Ok, vielen Dank 🙂
InformationsquelleAutor Martin Beckett
Laut deinem geposteten code, ich denke, dass Sie einen Fehler gemacht haben bei dieser Linie.
Sie versuchen, etwas zu schreiben, in der file_to_copy, die ist bereits geschlossen, das ist nicht erlaubt, die von dem Programm, es gibt Ihnen also einen stackoverflow.
InformationsquelleAutor MYMNeo