linux编程学习笔记(九) 获取文件状态与文件映射mmap


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比原来的小,则在截断文件


#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 100644
	
	
	ftruncate(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使用内存方式写入数据

#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使用内存方式读取数据

#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);
	if(fd < 0)
	{
		perror("open fail");
		return 1;
	}
	
	struct stat st;
	fstat(fd,&st);
	int size = st.st_size;
	int count = size/sizeof(struct stu);
	
	struct stu*s = mmap(0,size,PROT_READ | PROT_WRITE,
		MAP_SHARED,fd,0);
	if(s < 0)
	{
		perror("mmap error");
		return 1;
	}
	
	int i =0;
	for(; i<count ;i++)
	{
		printf("name:%s,age:%d,score:%.2f\n",s[i].name,s[i].age,s[i].score);
	}
	
	
	munmap(s,size);
	close(fd);
	
}






你可能感兴趣的:(linux编程学习笔记(九) 获取文件状态与文件映射mmap)