使用mmap()和使用 read()write()实现文件拷贝的对比
来源:互联网 发布:淘宝网店开店方案 编辑:程序博客网 时间:2024/05/16 04:05
最近上课老师说了这样一句话:mmap()内存映射可以实现文件的拷贝,并且速度明显快于一般的文件拷贝,于是
我试着实现了两种文件拷贝所花费时间的比较,首先看代码:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <sys/time.h>
#include <string.h>
#define BUFFER_SIZE 1
void my_copy1()
{
int fin,fout;
void *start;
void *end;
struct stat sb;
if((fin = open("file.in",O_RDONLY)) < 0){
perror("open error");
exit(EXIT_FAILURE);
}
if((fout = open( "file.out",O_RDWR | O_CREAT | O_TRUNC,00600)) < 0 ){
perror( "write error" );
exit( EXIT_FAILURE );
}
fstat(fin,&sb);
if(lseek(fout,sb.st_size-1,SEEK_SET) < 0 ){
exit(EXIT_FAILURE);
}
if(write(fout, &sb,1) != 1 ){
exit(EXIT_FAILURE);
}
start = mmap(NULL,sb.st_size,PROT_READ,MAP_PRIVATE,fin,0);
if(start == MAP_FAILED)
return;
end = mmap(0,(size_t)sb.st_size,PROT_WRITE,MAP_SHARED,fout,0);
if(end == MAP_FAILED){
perror( "mmap target" );
exit( EXIT_FAILURE );
}
memcpy(end,start,(size_t)sb.st_size);
munmap(start,sb.st_size); //关闭映射
close(fin);
close(fout);
return;
}
void my_copy2()
{
int fin,fout;
int bytes_read,bytes_write;
char buffer[BUFFER_SIZE];
char *ptr;
if((fin = open("file.in",O_RDONLY)) < 0){
perror("open error");
exit(EXIT_FAILURE);
}
if((fout = open( "file.out",O_RDWR | O_CREAT | O_TRUNC,00700)) < 0 ){
perror( "write error" );
exit( EXIT_FAILURE );
}
while(bytes_read=read(fin,buffer,BUFFER_SIZE)){
if((bytes_read==-1)&&(errno!=EINTR))
break;
else if(bytes_read>0){
ptr=buffer;
while(bytes_write=write(fout,ptr,bytes_read)){
if((bytes_write==-1)&&(errno!=EINTR))
break;
else if(bytes_write==bytes_read)
break;
else if(bytes_write>0){
ptr+=bytes_write;
bytes_read-=bytes_write;
}
}
if(bytes_write==-1)
break;
}
}
close(fin);
close(fout);
return;
}
main()
{
struct timeval tv;
struct timezone tz;
int time_start,time_end;
gettimeofday(&tv,&tz);
time_start = (int)tv.tv_usec;
my_copy1();
printf("/ndone./n/n");
gettimeofday(&tv,&tz);
time_end = (int)tv.tv_usec;
printf("using /"mmap()/" to copy costs %d microseconds /n",time_end-time_start);
gettimeofday(&tv,&tz);
time_start = (int)tv.tv_usec;
my_copy2();
gettimeofday(&tv,&tz);
time_end = (int)tv.tv_usec;
printf("using /"read() and write()/" to copy costs %d microseconds /n",time_end-time_start);
}
代码不是很难,中间使用了一些LinuxC的一些函数,不懂的可以自己查阅相关资料。我现在主要使想就两种
不同的拷贝的实现在所花费的时间上的一些比较以及的出我自己的一些观点,调试程序时可以将BUFFER_SIZE
随意更改一个数字,表示的是使用read函数从文件中一次读取的字符个数。当然,强调了这个必然有原因。
如果BUFFER_SIZE很小的话,最终的结果差别很大。比如我的
BUFFER_SIZE=1时我的运行结果如下:
zhou@zhou:~/LinuxC/file/mmcopy$ ./mmap
done.
using "mmap()" to copy costs 591 microseconds
using "read() and write()" to copy costs 505337 microseconds
zhou@zhou:~/LinuxC/file/mmcopy$
两个完全不是一个数量级的。下面换个数字
BUFFER_SIZE=10000时我的运行情况如下:
zhou@zhou:~/LinuxC/file/mmcopy$ ./mmap
done.
using "mmap()" to copy costs 594 microseconds
using "read() and write()" to copy costs 585 microseconds
zhou@zhou:~/LinuxC/file/mmcopy$
这时两个的消耗时间很接近,可以想象。如果BUFFER_SIZE定义的很大的话,那么read()write()方法将会
非常快,但是。如果你要拷贝的文件很小呢,加入只有100字节,但是你却每次申请10000个字节,这样岂不
是很浪费内存。这也就是mmap()的优势,不仅没有浪费内存,而且速度相当的快。
话题一转,这是为什么呢,我的理解使这样的:mmap首先将要拷贝的文件的内容全部映射到内存,然后写到目
的文件,总共的磁盘操作就两次,而read()write()不同,会根据你的BUFFER_SIZE定义的,然后会执行
(文件内容的总的字节数/BUFFER_SIZE)*2 次的磁盘操作,因此在这上面浪费了大量的时间。所以了
好的,就这么多了,如果有什么问题可以直接留言,互相讨论,谢谢
- 使用mmap()和使用 read()write()实现文件拷贝的对比
- 使用mmap实现文件的拷贝
- mmap和read、write
- C++类中包含string类型数据使用read和write实现文件读取和输出时遇到的问题
- Linux下的C语言编程——系统调用read和write函数实现文件拷贝
- 【Linux】使用read、write、lseek函数实现文件读写操作
- 经常使用的read & write
- mmap与read/write的区别
- mmap与read/write的区别
- 使用mmap实现文件映射
- read/write&mmap&aio
- (八)read和write函数的使用
- read/write函数实现文件的copy
- read,write和lseek函数使用实例
- 利用mmap实现文件拷贝
- 使用mmap即文件映射实现文件的快速复制
- 同步拷贝文件read write fcntl
- FileStream之Seek、Read、Write的使用
- 指针的一个妙用
- Ubuntu忘记密码的解决方法
- epoll精髓
- 快速傅里叶变换(FFT)(ZZ)
- VB句柄概念-不懂以后深入理解
- 使用mmap()和使用 read()write()实现文件拷贝的对比
- extern用法详解
- java新特性(反射和注记)(续)
- FP编程实践:在C++0x中模拟F#的List.map和List.choose库函数
- 网址收录
- 最热门的IT论坛集合
- VS 2010 正式版 下载
- 【转载】ExtJs grid 回调函数里Function()参数里的具体意义及如何带参数掉函数
- 华清远见高级讲师蒙洋接受至顶网专访:Windows CE 6.0 R3让用户界面更炫