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

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

作者: 木鱼_cc | 来源:发表于2018-05-24 22:31 被阅读0次

    1.stat文件

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

    #include <sys/stat.h>//头文件
    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 <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/stat.h>
    #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<MAX_MEM)
        {
            max = st.st_size
        }
        else
        {
            max= MAX_MEM;
        }
        char *buf = malloc(max);//文件多大,就分配多大的一个堆空间
       
        while(1)
        {
               int rc = fread(buf,1,max,p1);
               if(rc == 0)break;
               fwrite(buf,1,rc,p1);
        }
      
        
       
    
        
        fclose(p1);
        fclose(p2);
        free(buf);
        return 0;
    }
    

    相关文章

      网友评论

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

          本文链接:https://www.haomeiwen.com/subject/hqzsjftx.html