手册上可以man到得,我这里就不说了。mmap文件应用一般就是:
1.复制文件
2.修改文件内容,但是不改变文件大小
3.修改文件大小
我分应用场景说说注意事项了
1.复制文件
复制文件,源文件没什么需要注意的,可是目的文件就要注意了.
fstat(fd,&st);//获得原文件大小
lseek(fd2,st.st_size-1,SEEK_SET);//设置目的文件大小
write(fd2,"",1); //必须的,如果不设置,当写入数据的时候会遇到文件结束符,产生SIGBUS信号
这个你们可以不要上面这个IO操作,write,确实是会出现总线错误的!!!
原因是:
lseek了一个空洞 但是并没有引起i/o操作,也就是说如果lseek之后没有发生i/o操作时,lseek只是把偏移量给改了一下并没有在磁盘上分配存储区而你的文件是新建的 存储的空间长度为0 lseek之后还是为0.把mmap到系统的线性地址空间,然后进行复制的话就会出错.
除了上面的一次IO操作,引起文件大小的改变外,还可以直接调用truncate和ftruncate修改文件大小,看看我程序里的做法就知道了,其实扩大容量也就是这么做的,先truncate使得文件大小增加.
2.修改直接见程序了,就相当于修改字符串!!!
3.文件大小就是先truncate增大文件大小了,至于减少文件大小,直接truncate,ftruncate就可以了,不需要mmap!!!!
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> #include <unistd.h> #include <fcntl.h> #include <sys/mman.h> #include <sys/stat.h> #include <sys/types.h>
int main(int argc,char *argv[]) { int fdin; char *str;
struct stat statbuf;
if(argc != 2) { printf("usage : %s \n",argv[0]); return -1; }
if((fdin = open(argv[1],O_RDWR)) == -1) { printf("can't open file %s\n",argv[1]); return -1; }
assert(fstat(fdin,&statbuf) == 0); printf("filein size = %ld\n",statbuf.st_size); ftruncate(fdin, statbuf.st_size+2);//增加文件大小 str = (char*)mmap(0,statbuf.st_size+2,PROT_READ|PROT_WRITE,MAP_SHARED,fdin,0); if( str == MAP_FAILED ) { printf("mmap error for fdin.\n"); return 1; } while(*str) { printf("%c\n",*str); str++; #if 0 //修改文件内容 if(*str=='\n') *str ='z'; #endif } *str++ = 'x'; *str++ = 'y'; *str++ = 'z';
munmap(str, statbuf.st_size+2); close(fdin);
return 0; }
|
阅读(4206) | 评论(1) | 转发(0) |