检查返回值fread和fwrite

#include  #include  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; } 

编辑:我已经更新了代码
我有些疑惑:
1)我必须检查fread的返回码,因为 – 例如 – 如果由于错误而字节变为0,则0将被写入复制的文件中。
但我的问题是:怎么做? 因为fread 可以返回0但也可以返回一个短值 ….
2)如何读取文件? 如果我复制一个5MB的文件,怎么可以从1MB中的1MB移动而没有对它说的话“嘿,你必须在你复制的1MB后放置1MB的偏移”?
3)为什么不在每次使用后清除缓冲液? 我的意思是:

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

通常,您希望尝试在单个读/写周期中复制整个文件。 这有(除其他外)你的内存分配失败的相当大的机会,或者如果你最终分配/使用一些虚拟内存,效率非常低。

相反,您通常希望分配一个合理大小的缓冲区(例如,一兆字节或两兆字节)然后在循环中进行复制,例如:

 char *buffer = malloc(1024 * 1024); while ((bytes=fread(buffer, 1, sizeof(buffer), infile)) > 0) fwrite(buffer, 1, bytes, outfile); 

当然,您也可以检查fwrite的返回值,并且(例如)如果没有写入您请求的数量,则退出循环。 例如,如果您正在移动文件而不是仅复制文件,这一点尤其重要 – 您只需要在/确定副本成功时删除原始文件。

如果fread / fwrite没有复制你期望的字符数,可以调用ferror()来检查I / O流的错误状态

根据你发布的代码,我认为你在这一行上犯了一个错误。

 fwrite(buffer, 1, file_size, file_to_copy); 

你试着把一些东西写入已经关闭的file_to_copy中,这是程序不允许的,所以它给你一个stackoverflow。