stat函数,fread和fwrite函数(二进制文件拷贝)

1.stat文件

stat命令来源于linux,用于查看文件的具体存储信息

#include //头文件
int  stat(const char * path, struct stat * buf)
//把path路径下的文件,交给buf代理
stat.st_size;//文件大小,单位:字节
函数的第一个参数代表文件名,第二个参数是struct stat结构。
得到文件的属性,包括文件建立时间,文件大小等信息。

  struct stat {
         dev_t     st_dev;     /* ID of device containing file */
         ino_t     st_ino;     /* inode number */
         mode_t    st_mode;    /* protection */
         nlink_t   st_nlink;   /* number of hard links */
         uid_t     st_uid;     /* user ID of owner */
         gid_t     st_gid;     /* group ID of owner */
         dev_t     st_rdev;    /* device ID (if special file) */
         off_t     st_size;    /* total size, in bytes */
         blksize_t st_blksize; /* blocksize for filesystem I/O */
         blkcnt_t  st_blocks;  /* number of 512B blocks allocated */
         time_t    st_atime;   /* time of last access */
         time_t    st_mtime;   /* time of last modification */
         time_t    st_ctime;   /* time of last status change */
 };

int main(){
  struct stat st = {0};
  stat("D:\\temp\\a.txt",&st);

  printf("%ld",st.st_size);

return 0
}

2.fread和fwrite函数

这两个函数时用于读写一个二进制文件的,因为fputs和fgets是针对文本文件,而图像,音频等都是二进制文件,需要其他的读取方式

size_t fread ( void *buffer, size_t size, size_t count, FILE *stream) ;




size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream);
第一个参数是buf的内存地址
第二个参数是写多少个单位
第三个参数是每个单位的大小
第四个参数是fopen返回的文件指针
只要第二个参数和第三个参数乘积一样,和第一个参数所指的内存区域一样大就可以。

注意:这个函数以二进制形式对文件进行操作,不局限于文本文件

返回值:返回实际写入的数据块数目
当fread的第二个参数是1的时候,可以认为fread返回的值是读取到的字节数
----------------------------------------------------------------
int main(){//fwrite

   int a = 100;
   FILE *p = fopen("D:\\temp\\a.dat","wb");
   //在windows读取二进制文件的时候都要加b,防止自动添加\r

   fwrite(&a,1,sizeof(int),p);
   //等价于 
   fwrite(&a,sizeof(int),1,p);
   //也等价于
   fwrite(&a,4,sizeof(char),p);




   int array[10] = {1,2,3,4,5,6,7,8,9,10};
   fwrite(array,1,sizeof(array),p);
   /*
   第一个参数是buf的内存地址
   第二个参数是写多少个单位
   第三个参数是每个单位的大小
   第四个参数是fopen返回的文件指针
   只要第二个参数和第三个参数乘积一样,和第一个参数所指的内存区域一样大就可以
   */



   fclose(p);
   return 0;

}


int main(){//fread

   FILE *p = fopen("D:\\temp\\a.dat","rb");
   

   while(!feof(p)){
 
       int a;
       if(fread(a,1,sizeof(a),p)==0)break;//解决多读最后一行的问题!
       //int rec = fread(a,1,sizeof(a),p); //一个单位是1个字节,fread的返回值代表读取了多少个单位
      // printf("rec = %d , a = %d\n",rec,a[i]);//输出rec = 4,代表返回了多少个单位
       
       //假设
       fread(buf,5,sizeof(int),p);//如果最后一次调用读取了3个int,那么返回0
   }

   fclose(p);
   return 0;
}

3.拷贝二进制文件

#include 
#include 
#include 
#include 
#pragma warning(disable:4996)


int main(){


      FILE *p1 = fopen("D:\\temp\\a.dat","rb");//音频文件都可以拷贝
      FILE *p2 = fopen("D:\\temp\\b.dat","wb");

      if (p1 == NULL)
      {
        return 0;
      }
      if (p2 == NULL)
      {
        return 0;
      }
    /*
      while(1)
      {
        int a;
        if (fread(&a,1,sizeof(a),p1)==0)break;
        //每一次只读1个单位,一个单位为4BYTE,造成的结果是文件大小总是4的倍数
        //如果是exe的话就运行不了了
        fwrite(&a,1,sizeof(a),p2);

      }
      下面改进===
      */
      int index = 0;//计数器
      while(1)
      {

        char buf[1024] = {0};
        int rc = fread(buf,1,sizeof(buf),p1);//rc可以认为是从p1中读取到的字节数
        if(rc==0)break;
        fwrite(&buf,1,rc,p2);//不是4个为1单位,而是rc为1单位,有4就4,不够就少一点
        index++;
      }
      printf("%d\n",index);
      fclose(p1);
      fclose(p2);

   return 0;
}



==============================提高效率,利用堆和stat================================
int main(){//没有考虑到堆不够的情况

      FILE *p1 = fopen("D:\\temp\\a.wmv","rb");
      FILE *p2 = fopen("D:\\temp\\b.wmv","wb");

      if (p1 == NULL)
      {
        return 0;
      }
      if (p2 == NULL)
      {
        return 0;
      }

    struct stat st = {0};
    stat("D:\\temp\\a.wmv",&st);
    char *buf = malloc(st.st_size);//文件多大,就分配多大的一个堆空间
    //要注意堆内存不够的情况
  
    fread(buf,1,st.st_size,p1);
    fwrite(buf,1,st.st_size,p1);

    
    fclose(p1);
    fclose(p2);
    free(buf);
    return 0;
}



==============================终极版提高效率================================
#define MAX_MEM   1024 * 1024 * 4 //阀值设置为4M
int main(int argc, char *args[]){//假设文件巨大


      if (argc < 3)
      {
         printf("参数不够\n");
         return 0;
      }
      FILE *p1 = fopen(args[1],"rb");//输入不需要转意符
      FILE *p2 = fopen(args[2],"wb");

      if (p1 == NULL)
      {
        printf("打开%s失败\n",args[1] );
        return 0;
      }
      if (p2 == NULL)
      {
        printf("打开%s失败\n",args[2] );
        return 0;
      }
    //设置一个阀值,如果低于这个阀值的话,那么就分配实际大小
      //如果高于这个阀值,那么就分配阀值的大小
    struct stat st = {0};
    stat(args[1],&st);
    int max;
    if(st.st_size

你可能感兴趣的:(stat函数,fread和fwrite函数(二进制文件拷贝))