linux编程--获取文件状态与文件映射mmap .

来源:互联网 发布:美工学徒带薪招聘骗局 编辑:程序博客网 时间:2024/06/07 11:43

来源 : http://blog.csdn.net/a8887396/article/details/9009485

 

1 fstat 获取文件状态     int fstat(int fd, struct stat *buf);


         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 file system 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 */
           };


2 ftruncate改变文件大小

       int ftruncate(int fd, off_t length);
如果length比原来的大,则在文件后面添加'\0'

如果length比原来的小,则在截断文件


[cpp] view plaincopyprint?
  1. #include <sys/types.h>   
  2. #include <sys/stat.h>   
  3.  #include <fcntl.h>   
  4. #include <unistd.h>   
  5. #include <stdio.h>   
  6.   
  7.   
  8. int main()  
  9. {  
  10.     int fd;  
  11.     struct stat st;  
  12.     fd = open("stu.dat",O_RDWR);  
  13.     fstat(fd,&st);  //错误:存储大小未知  没加头文件  
  14.     printf("%d,%o\n",(int)st.st_size,st.st_mode); //72 100644  
  15.       
  16.       
  17.     ftruncate(fd,st.st_size+1000); // 需要写权限才能改变大小  
  18.     fstat(fd,&st);  
  19.     printf("%d\n",(int)st.st_size);  
  20.     close(fd);  
  21.       
  22. }  
#include <sys/types.h>#include <sys/stat.h> #include <fcntl.h>#include <unistd.h>#include <stdio.h>int main(){int fd;struct stat st;fd = open("stu.dat",O_RDWR);fstat(fd,&st);  //错误:存储大小未知  没加头文件printf("%d,%o\n",(int)st.st_size,st.st_mode); //72 100644ftruncate(fd,st.st_size+1000); // 需要写权限才能改变大小fstat(fd,&st);printf("%d\n",(int)st.st_size);close(fd);}


zhao@ubuntu:~/unix/4$ ./fstat 
72,100644
1072


3  文件映射

mmap /munmap

之前介绍过(http://blog.csdn.net/a8887396/article/details/8996213) ,写的是内存映射,拷过来

void *mmap(
void *start, //指定映射的虚拟地址  如为0 系统指定开始位置
size_t length, //映射的空间大小 : pagesize倍数
int prot,//映射权限 PROT_NONE PROT_READ PROT_WRITE PROT_EXEC
int flags,//映射方式
int fd,//文件描述符
offset_t  off); //文件中的偏移位置(必须是page_size的倍数)
       int munmap(void *addr, size_t length);
       映射方式:
内存映射:匿名映射
文件映射:映射到文件 ,只有当文件映射时,最后两个参数才有效
MAP_ANONYMOUS 写了就是内存映射 不写就是文件映射
MAP_PRIVATE MAP_SHARED 2选1

  umap(void *start,size_t lenth)

案例:
1使用内存方式写入数据

[cpp] view plaincopyprint?
  1. #include <stdio.h>   
  2. #include <stdlib.h>   
  3. #include <sys/types.h>   
  4. #include <sys/stat.h>   
  5. #include <fcntl.h>   
  6. #include <unistd.h>   
  7. #include <string.h>   
  8. #include <sys/mman.h>   
  9.   
  10.   
  11. struct stu  
  12. {  
  13.     char name[20];  
  14.     int age;  
  15.     float score;  
  16. };  
  17.   
  18. int main()  
  19. {  
  20.     //打开文件   
  21.     //增加文件大小   
  22.     //映射到虚拟地址   
  23.     //把数据写入虚拟地址   
  24.     //卸载虚拟地址   
  25.     //关闭文件   
  26.       
  27.     int fd = open("newstu.dat",O_RDWR|O_CREAT,0666);  
  28.     if(fd < 0)  
  29.     {  
  30.         perror("open error");  
  31.         return 1;  
  32.     }  
  33.     struct stat st;  
  34.     fstat(fd,&st);  
  35.     int size = st.st_size ; //文件大小  
  36.     int count = size/sizeof(struct stu);//记录条数  
  37.     //因为要增加数据 所以要先增加文件大小(很重要)   
  38.     ftruncate(fd,size+sizeof(struct stu)); //增加文件大小  
  39.       
  40.     //将文件映射到内存的虚拟地址,得到文件在虚拟内存中映射的首地址    
  41.     struct stu*s= mmap(0,  
  42.                size+sizeof(struct stu),  
  43.                PROT_WRITE|PROT_READ,  
  44.                MAP_SHARED,  
  45.                fd,0);  
  46.   
  47.     printf("请输入学生姓名");  
  48.     scanf("%s",s[count].name);  
  49.     printf("请输入学生年龄");  
  50.     scanf("%d",&s[count].age);  
  51.     printf("请输入学生成绩");  
  52.     scanf("%f",&s[count].score);  
  53.     munmap(s,size+sizeof(struct stu));  
  54.       
  55.     close(fd);  
  56.       
  57. }  
#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <string.h>#include <sys/mman.h>struct stu{char name[20];int age;float score;};int main(){//打开文件//增加文件大小//映射到虚拟地址//把数据写入虚拟地址//卸载虚拟地址//关闭文件int fd = open("newstu.dat",O_RDWR|O_CREAT,0666);if(fd < 0){perror("open error");return 1;}struct stat st;fstat(fd,&st);int size = st.st_size ; //文件大小int count = size/sizeof(struct stu);//记录条数//因为要增加数据 所以要先增加文件大小(很重要)ftruncate(fd,size+sizeof(struct stu)); //增加文件大小//将文件映射到内存的虚拟地址,得到文件在虚拟内存中映射的首地址 struct stu*s= mmap(0,   size+sizeof(struct stu),   PROT_WRITE|PROT_READ,   MAP_SHARED,   fd,0);printf("请输入学生姓名");scanf("%s",s[count].name);printf("请输入学生年龄");scanf("%d",&s[count].age);printf("请输入学生成绩");scanf("%f",&s[count].score);munmap(s,size+sizeof(struct stu));close(fd);}


2使用内存方式读取数据

[cpp] view plaincopyprint?
  1. #include <stdio.h>   
  2. #include <stdlib.h>   
  3. #include <sys/types.h>   
  4. #include <sys/stat.h>   
  5. #include <fcntl.h>   
  6. #include <unistd.h>   
  7. #include <string.h>   
  8. #include <sys/mman.h>   
  9.   
  10. struct stu  
  11. {  
  12.     char name[20];  
  13.     int age;  
  14.     float score;  
  15. };  
  16.   
  17. int main()  
  18. {  
  19.     int fd = open("newstu.dat",O_RDWR);  
  20.     if(fd < 0)  
  21.     {  
  22.         perror("open fail");  
  23.         return 1;  
  24.     }  
  25.       
  26.     struct stat st;  
  27.     fstat(fd,&st);  
  28.     int size = st.st_size;  
  29.     int count = size/sizeof(struct stu);  
  30.       
  31.     struct stu*s = mmap(0,size,PROT_READ | PROT_WRITE,  
  32.         MAP_SHARED,fd,0);  
  33.     if(s < 0)  
  34.     {  
  35.         perror("mmap error");  
  36.         return 1;  
  37.     }  
  38.       
  39.     int i =0;  
  40.     for(; i<count ;i++)  
  41.     {  
  42.         printf("name:%s,age:%d,score:%.2f\n",s[i].name,s[i].age,s[i].score);  
  43.     }  
  44.       
  45.       
  46.     munmap(s,size);  
  47.     close(fd);  
  48.       
  49. }  
原创粉丝点击