主要用途如下:
1、将一个普通文件映射到内存中,通常在需要对文件进行频繁读写时使用,这样用内存读写取代I/O读写,以获得较高的性能;
2、将特殊文件进行匿名内存映射,可以为关联进程提供共享内存空间(fork 之后,在子进程中操作描述符而不用创建)
3、为无关联的进程提供共享内存空间,一般也是将一个普通文件映射到内存中(进程通信)
4、大文件的读取
待续: https://www.cnblogs.com/alantu2018/p/8506381.html
大文件拷贝例子:
1、用内存映射的方法
// file my_copy.c
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <time.h>
#define BUF_SIZE (4096*1000) // sysconf(_SC_PAGE_SIZE) 的整数倍
// 线程栈 的大小默认是 8M + 4K(溢出保护检测区域),所以超过这个大小就会报错
int main(int argc,char *argv[])
{
int fd_r,fd_w;
char * p_w,*p_r;
unsigned long int length_r,length_w,len = 0;
unsigned long int off= 0;
clock_t times = 0;
assert(argc == 3);
fd_r = open(argv[1],O_RDWR);
assert(fd_r);
fd_w = open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0644);
assert(fd_w);
length_r = lseek(fd_r,0,SEEK_END);
length_w = lseek(fd_w,length_r - 1,SEEK_CUR);
write(fd_w,"",1); //防止 bus error
lseek(fd_w,0,SEEK_SET);
lseek(fd_r,0,SEEK_SET);
printf("page size = %d \n", _SC_PAGE_SIZE);
printf("sysconf(_SC_PAGE_SIZE) size = %d \n\n", (int)sysconf(_SC_PAGE_SIZE));
while(1)
{
if((off + BUF_SIZE) >= length_r)
{
len = length_r - off;
p_r = mmap(NULL,BUF_SIZE,PROT_READ|PROT_WRITE,MAP_SHARED,fd_r,off);
p_w = mmap(NULL,BUF_SIZE,PROT_WRITE,MAP_SHARED,fd_w,off);
memcpy(p_w,p_r,len);
munmap(p_r,BUF_SIZE);
munmap(p_w,BUF_SIZE);
break;
}
else
{
len = BUF_SIZE;
}
p_r = mmap(NULL,BUF_SIZE,PROT_READ|PROT_WRITE,MAP_SHARED,fd_r,off);
p_w = mmap(NULL,BUF_SIZE,PROT_WRITE,MAP_SHARED,fd_w,off);
memcpy(p_w,p_r,len);
munmap(p_r,BUF_SIZE);
munmap(p_w,BUF_SIZE);
off += len;
}
times = clock();
printf("%lu \n", times);
close(fd_r);
close(fd_w);
times = clock();
printf("%lu \n", times);
return 0;
}
//gcc -o my_copy my_copy.c
// ./my_copy file1 file2
// cmp -b file1 file2
// 一样的话,无输出
2、不用内存映射的方法
试了一下,2G的文件 速度差不多,有时候反而比上面快一些
//#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#define BUF_SIZE (4096*1000)
char buf[BUF_SIZE];
int main(int argc,char *argv[])
{
//int fd_r,fd_w;
FILE *fd_r = NULL;
FILE *fd_w = NULL;
size_t read_len = 0;
clock_t times = 0;
long unsigned int length_r,length_w,len = 0;
long unsigned int off= 0;
assert(argc == 3);
//fd_r = open(argv[1],O_RDWR);
fd_r=fopen(argv[1],"r");
assert(fd_r);
fd_w=fopen(argv[2],"wr");
assert(fd_w);
fseek(fd_r,0,SEEK_END);
length_r = ftell(fd_r);
fseek(fd_r,0,SEEK_SET);
printf("read file len: %lu \n", length_r);
while(1)
{
memset(buf, 0, BUF_SIZE);
read_len=fread(buf, 1, BUF_SIZE, fd_r);
if(read_len > 0)
fwrite(buf, read_len, 1, fd_w);
if(read_len < BUF_SIZE)
{
off += read_len;
break;
}
off += BUF_SIZE;
}
printf("write file len: %lu \n", off);
times = clock();
printf("write over cost time: %lu \n", times);
fclose(fd_r);
fclose(fd_w);
times = clock();
printf("all over cost time: %lu \n", times);
return 0;
}
。。。
参照: https://blog.youkuaiyun.com/nocodelife/article/details/8647499