检查返回值fread和fwrite [英] check return value fread and fwrite

查看:95
本文介绍了检查返回值fread和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;
}

我已经更新了代码
我有一些疑问:
1)我必须检查fread的返回码,因为-例如-如果字节由于错误而变为0,则将0复制到复制的文件中.
但是我的问题是:该怎么做?因为fread 可以返回0,但也可以返回短值 ....
2)如何读取文件中的内容?如果我复制一个5MB的文件,那么如何在1MB到1MB的范围内进行读取而又没有对它说嘿,您必须将偏移量放在刚复制的1MB之后1MB"?
3)为什么每次使用后不清除缓冲区?我的意思是:

i've updated the code
I have some doubts:
1) I have to check the return code of fread because - for example - if bytes become 0 due to an error, 0 will be written into the copied file.
But my question is: how to do it? Because fread can return 0 but can also return a short value ....
2) how can read go throught the file? If i copy a 5MB file how can fread move from 1MB in 1MB without something that say to it "hey you have to put your offset 1MB after the 1MB you've just copied"?
3) why not to clear the buffer after every use? I mean something like:

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

推荐答案

通常,您不想想要尝试在单个读/写周期中复制整个文件. (除其他事项外)这很有可能导致内存分配失败,或者如果最终分配/使用了一些虚拟内存,则效率极低.

Usually, you don't want to try to copy an entire file in a single read/write cycle. This has (among other things) a fairly substantial chance of your memory allocation failing, or being horribly inefficient if you end up allocating/using some virtual memory.

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

Instead, you usually want to allocate a buffer of reasonable size (say, a megabyte or two) then do the copying in a loop, something like:

char *buffer = malloc(1024 * 1024);  

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

当然,您也可以检查fwrite的返回值,例如,如果循环中未写入您要求的金额,则退出循环.例如,这是非常重要的,例如,您要移动文件而不是仅复制文件时-仅在确定复制成功后才想删除原始文件.

You can, of course, also check the return value from fwrite and (for example) exit the loop if it doesn't write the amount you requested. This is particularly important if, for example, you're moving a file instead of just copying it -- you only want to remove the original when/if you're certain the copy has succeeded.

这篇关于检查返回值fread和fwrite的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆