内存映射和文件操作函数

来源:互联网 发布:linux压缩多个文件夹 编辑:程序博客网 时间:2024/05/17 02:10

内存映射

 mmap的函数定义:  void *mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset);
  • 函数参数详细解
    • 参数fd为即将映射到进程空间的文件描述字,一般由open()返回,同时,fd可以指定为-1,此时须指定flags参数中的MAP_ANON,表明进行的是匿名映射(不涉及具体的文件名,避免了文件的创建及打开,很显然只能用于具有亲缘关系的进程间通信)。
    • len是映射到调用进程地址空间的字节数,它从被映射文件开头offset个字节开始算起。
    • prot参数指定共享内存的访问权限。可取如下几个值的或:PROT_READ(可读),PROT_WRITE(可写),PROT_EXEC(可执行),PROT_NONE(不可访问)。
    • flags由以下几个常值指定:MAP_SHARED,MAP_PRIVATE,MAP_FIXED。其中,MAP_SHARED,MAP_PRIVATE必选其一,而MAP_FIXED则不推荐使用。如果指定为MAP_SHARED,则对映射的内存所做的修改同样影响到文件。如果是MAP_PRIVATE,则对映射的内存所做的修改仅对该进程可见,对文件没有影响。
    • offset参数一般设为0,表示从文件头开始映射。
    • 参数addr指定文件应被映射到进程空间的起始地址,一般被指定一个空指针,此时选择起始地址的任务留给内核来完成。函数的返回值为最后文件映射到进程空间的地址,进程可直接操作起始地址为该值的有效地址。
    • 函数内部机制原理
    • mmap系统调用并不是完全为了用于共享内存而设计的。它本身提供了不同于一般对普通文件的访问方式,进程可以像读写内存一样对普通文件的操作。而Posix或系统V的共享内存IPC则纯粹用于共享目的,当然mmap()实现共享内存也是其主要应用之一。
    • mmap系统调用使得进程之间通过映射同一个普通文件实现共享内存。普通文件被映射到进程地址空间后,进程可以像访问普通内存一样对文件进行访问,不必再调用read(),write()等操作。
    • 我们的程序中大量运用了mmap,用到的正是mmap的这种“像访问普通内存一样对文件进行访问”的功能。实践证明,当要对一个文件频繁的进行访问,并且指针来回移动时,调用mmap比用常规的方法快很多。
  • 存储映射例子
#include<iostream>#include<fstream>#include<sstream>#include<cstdlib>#include<cstdio>#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>#include<sys/mman.h>#include<string>#include<unistd.h>int main(int argc,char* argv[]){    struct stat buf;    stat(argv[1],&buf);    printf("file size is %u",buf.st_size);    int fd=open(argv[1],O_RDONLY);    char* p=(char*)mmap(NULL,buf.st_size,PROT_READ,MAP_SHARED,fd,0);    puts(p);    std::istringstream ss;    std::string word;    ss.str(p);    int count=0;    while(ss>>word)    {        std::cout<<word<<std::endl;        count++;    }    std::cout<<"count is "<<count<<std::endl;    return 0;    for(int i=0;i<buf.st_size;i++)    {        printf("%c",p[i]);    }}

文件操作函数

  • 块读入数据,弊端不能识别数据格式,需要另行处理
       size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);       size_t fwrite(const void *ptr, size_t size, size_t nmem,FILE *stream);
  • 按指定格式输入输出,可以方便的处理数据
       int fscanf(FILE *stream, const char *format, ...);       int sscanf(const char *str, const char *format, ...);
  • 字符串拼接和提取函数
       int sscanf(const char *str, const char *format, ...);                   字符流动方向---->       int sprintf(char *restrict s, const char *restrict format, ...);                                      <----字符流动方向
  • 文件描述符读写函数
       ssize_t write(int fildes, const void *buf, size_t nbyte);        ssize_t read(int fildes, const void *buf, size_t nbyte); 
0 0
原创粉丝点击