在linux中使用内存映射(mmap)操作文件
2013-11-15 16:50
337 查看
在使用内存映射操作文件之前,我们先按照常规的方式来读写文件,这种方式操作如下:
1,打开或创建文件,得到文件描述符,
2,将内存中的数据以一定的格式和顺序写入文件,或者将文件中的数据以一定的格式和顺序读入到内存;
3,关闭文件描述符;
下边是按照常规方式操作固定格式的文件的方法,包含读写两个示例;
以上操作文件的方式只能操作小文件,如果文件很大,就无法一次载入内存操作,我们就需要用到内存映射技术来操作;具体实现如下:
1,首先打开文件,使用的函数原型如下:
int open( //返回值:大于等于0代表操作成功,返回打开的文件描述符号,=-1,创建或者打开失败,失败可查阅errorno来获取具体错误信息
const char *pathname, //要打开的文明名
int flags, //打开的方式,打开方式包括:O_RDONLY 只读方式 O_WRONLY 只写,O_RDWR读写,O_CREAT创建,O_EXCL文件如果存在,使用此标记,会返回错误
mode_t mode); //指定创建文件的权限,只对创建文件有效,对于打开无效;
2,获取文件大小
int fstat(int fd,//文件描述符号
struct stat*buf);//返回文件属性结构体
返回值:成功返回0;失败返回-1
3,把文件映射成虚拟内存
void *mmap(void *addr, //从进程的那个地址开始映射,如果为NULL,由系统指定;
size_t length, //映射的地址空间的大小
int prot, //内存的保护模式
int flags,//映射模式 有匿名,私有,保护等标记 具体查询man手册;
int fd, //如果为文件映射,则此处为文件的描述符号
off_t offset);//如果为文件映射,则此处代表定位到文件的那个位置,然后开始向后映射。
返回值:映射成功,返回首地址;
4,通过对内存的读写来实现对文件的读写
通常使用:memset 和memcpy来实现操作;
5,卸载映射
int munmap(void *addr, //要卸载的内存的地址
size_t length);//内存的大小
6,关闭文件
int close(int fd); //要关闭的文件描述符号 ,成功返回0,错误返回-1,错误参照errorno;
下边是读取文件的操作:
1,打开或创建文件,得到文件描述符,
2,将内存中的数据以一定的格式和顺序写入文件,或者将文件中的数据以一定的格式和顺序读入到内存;
3,关闭文件描述符;
下边是按照常规方式操作固定格式的文件的方法,包含读写两个示例;
#include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <string.h> //写内存到文件 struct student{ char name[20]; short age; float score; char sex; }; int main() { struct student stu[5]; mode_t mode; mode=umask(000); int fd=open("user.dat",O_RDWR|O_CREAT|O_EXCL,00666); if(fd==-1){ printf("open:%m\n"); umask(mode); exit(-1); } printf("ok\n"); memset(stu,0,sizeof(stu)); int i=0; for(;i<5;i++){ memcpy(stu[i].name,"tom",strlen("tom")+1); stu[i].age=i; stu[i].score=89.12f; stu[i].sex='m'; write(fd,&stu[i],sizeof(stu[i])); } close(fd); umask(mode); return 0; }
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <string.h> typedef struct{ char name[20]; short age; float score; char sex; }Student; //读取文件到内存 int main() { Student stu[5]; mode_t mode; mode=umask(0000); int fd=open("user.dat",O_RDWR,0666); if(fd==-1){ printf("open:%m\n"); umask(mode); exit(-1); } printf("open ok! can read;\n"); int i=0; for(;i<5;i++){ read(fd,&stu[i],sizeof(stu[i])); } close(fd); i=0; for(;i<5;i++){ printf("stu[%d].name=%s\n",i,stu[i].name); printf("stu[%d].age=%d\n",i,stu[i].age); printf("stu[%d].sex=%c\n",i,stu[i].sex); printf("stu[%d].score=%f\n",i,stu[i].score); } umask(mode); return 0; }
以上操作文件的方式只能操作小文件,如果文件很大,就无法一次载入内存操作,我们就需要用到内存映射技术来操作;具体实现如下:
1,首先打开文件,使用的函数原型如下:
int open( //返回值:大于等于0代表操作成功,返回打开的文件描述符号,=-1,创建或者打开失败,失败可查阅errorno来获取具体错误信息
const char *pathname, //要打开的文明名
int flags, //打开的方式,打开方式包括:O_RDONLY 只读方式 O_WRONLY 只写,O_RDWR读写,O_CREAT创建,O_EXCL文件如果存在,使用此标记,会返回错误
mode_t mode); //指定创建文件的权限,只对创建文件有效,对于打开无效;
2,获取文件大小
int fstat(int fd,//文件描述符号
struct stat*buf);//返回文件属性结构体
返回值:成功返回0;失败返回-1
3,把文件映射成虚拟内存
void *mmap(void *addr, //从进程的那个地址开始映射,如果为NULL,由系统指定;
size_t length, //映射的地址空间的大小
int prot, //内存的保护模式
int flags,//映射模式 有匿名,私有,保护等标记 具体查询man手册;
int fd, //如果为文件映射,则此处为文件的描述符号
off_t offset);//如果为文件映射,则此处代表定位到文件的那个位置,然后开始向后映射。
返回值:映射成功,返回首地址;
4,通过对内存的读写来实现对文件的读写
通常使用:memset 和memcpy来实现操作;
5,卸载映射
int munmap(void *addr, //要卸载的内存的地址
size_t length);//内存的大小
6,关闭文件
int close(int fd); //要关闭的文件描述符号 ,成功返回0,错误返回-1,错误参照errorno;
下边是读取文件的操作:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <sys/mman.h> #include <sys/stat.h> typedef struct{ char name[20]; short age; float score; char sex; }student; int main() { student *p,*pend; //打开文件描述符号 int fd; /*打开文件*/ fd=open("user.dat",O_RDWR); if(fd==-1){//文件不存在 fd=open("user.dat",O_RDWR|O_CREAT,0666); if(fd==-1){ printf("打开或创建文件失败:%m\n"); exit(-1); } } //打开文件ok,可以进行下一步操作 printf("open ok!\n"); //获取文件的大小,映射一块和文件大小一样的内存空间,如果文件比较大,可以分多次,一边处理一边映射; struct stat st; //定义文件信息结构体 /*取得文件大小*/ int r=fstat(fd,&st); if(r==-1){ printf("获取文件大小失败:%m\n"); close(fd); exit(-1); } int len=st.st_size; /*把文件映射成虚拟内存地址*/ p=mmap(NULL,len,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0); if(p==NULL || p==(void*)-1){ printf("映射失败:%m\n"); close(fd); exit(-1); } /*定位到文件开始*/ pend=p; /*通过内存读取记录*/ int i=0; while(i<(len/sizeof(student))) { printf("第%d个条\n",i); printf("name=%s\n",p[i].name); printf("age=%d\n",p[i].age); printf("score=%f\n",p[i].score); printf("sex=%c\n",p[i].sex); i++; } /*卸载映射*/ munmap(p,len); /*关闭文件*/ close(fd); }
相关文章推荐
- linux中使用内存映射(mmap)操作文件的方法
- 在linux中使用内存映射(mmap)操作文件的方法
- Android使用Linux命令执行文件操作
- Day25、malloc 内存分配、mmap内存映射、文件的操作(文件描述符、open\close\read)
- Linux下C编程-----IO/文件操作/内存映射 实现简单记录存储(3)
- [Linux流操作]使用fprintf函数将字符串写入文件
- linux svn 批量操作文件 及 各命令使用详解
- Android使用Linux命令执行文件操作
- Linux中tar命令操作文件的基本使用教程
- [Linux文件属性]使用utime函数操作文件的时间参数
- 如何在linux下使用c语言操作临时文件
- 如何在linux下使用c语言操作临时文件
- 12_Linux基础知识及命令――――使用通配符来操作文件
- [Linux流操作]使用gets和puts读写文件
- 在linux下使用c语言操作临时文件
- 关于qt在linux下使用open,write,close等文件操作的笔记
- [Linux流操作]使用fread和fwrite函数读写文件
- linux下命令行的使用:使用sed命令操作文件
- linux下文件的读写操作、字符串的处理操作,多线程操作等相关函数使用说明
- 【C语言】【unix c】使用mmap将文件映射到进程的虚拟地址空间,然后对内存的操作直接反应到文件中