检查返回值 fread 和 fwrite

pol*_*nux 2 c return-value fwrite fread

#include <stdio.h>\n#include <stdlib.h>\n\nint main(int argc, char *argv[]){\n\n  if(argc != 3){\n    printf("Usage: ./copy filename newfile\\n");\n    exit(1);\n  }\n\n  int bytes;\n  long file_size, file_copied_size;\n  FILE *file_to_copy, *new_file;\n\n  if((file_to_copy = fopen(argv[1], "rb")) == NULL){\n    printf("File cannot be opened - read\\n");\n    exit(1);\n  }\n  if((new_file = fopen(argv[2], "wb")) == NULL){\n    printf("File cannot be opened - write\\n");\n    exit(1);\n  }\n\n  fseek(file_to_copy, 0, SEEK_END);\n  file_size = ftell(file_to_copy);\n  rewind(file_to_copy);\n\n  char *buffer = malloc(1024 * 1024); /* Imposto un buffer di 1MB per maggiore efficienza */ \n  if(!buffer){\n    printf("Errore allocazione memoria\\n");\n    fclose(file_to_copy);\n    fclose(new_file);\n    exit(1);\n  }\n\n   /* In questo modo copio file grandi 1MB alla volta cos\xc3\xac il trasferimento \xc3\xa8 pi\xc3\xb9 veloce ed efficiente inoltre fread() ritorna 0 quando c\'\xc3\xa8 un errore o quando incontra EOF */\n  //while ((bytes=fread(buffer, 1, sizeof(buffer), file_to_copy)) > 0){\n  while (!feof(file_to_copy)){\n    bytes = fread(buffer, 1, sizeof(buffer), file_to_copy);\n    fwrite(buffer, 1, bytes, new_file);\n    if(ferror(new_file)){\n      perror("Errore scrittura"); /* perror printa anche l\'errore che ferror ha incontrato */\n      fclose(file_to_copy);\n      fclose(new_file);\n      exit(1);\n    }\n  }\n\n  fseek(new_file, 0, SEEK_END);\n  file_copied_size = ftell(new_file);\n  rewind(new_file);\n  if(file_size != file_copied_size){\n    printf("Il file %s non \xc3\xa8 stato copiato correttamente\\n", argv[2]);\n  }\n  else{\n    printf("File successfully copied :)\\n");\n  }  \n  fclose(file_to_copy);\n  fclose(new_file);\n  free(buffer);\n\n  return EXIT_SUCCESS;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n
while (!feof(file_to_copy)){\n        bytes = fread(buffer, 1, sizeof(buffer), file_to_copy);\n        fwrite(buffer, 1, bytes, new_file);\n        memset(buffer, 0, sizeof(buffer));\n}\n
Run Code Online (Sandbox Code Playgroud)\n

Jer*_*fin 5

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

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

char *buffer = malloc(1024 * 1024);  

while ((bytes=fread(buffer, 1, 1024 * 1024, infile)) > 0)
    fwrite(buffer, 1, bytes, outfile);
Run Code Online (Sandbox Code Playgroud)

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