當前位置:編程學習大全網 - 源碼下載 - Linux下的幾種文件拷貝方式效率對比

Linux下的幾種文件拷貝方式效率對比

不管是哪種操作系統,要實現文件拷貝,必須陷入內核,從磁盤讀取文件內容,然後存儲到另壹個文件。實現文件拷貝最通常的做法是:讀取文件用系統調用read()函數,讀取到壹定長度的連續的用戶層緩沖區,然後使用write()函數將緩沖區內容寫入文件。也可以用標準庫函數fread()和fwrite(),但這兩個函數最終還是通過系統調用read()和write()實現拷貝的,因此可以歸為壹類(不過效率肯定沒有直接進行系統調用的高)。壹個更高級的做法是使用虛擬存儲映射技術進行,這種方法將源文件以***享方式映射到虛擬存儲器中,目的文件也以***享方式映射到虛擬地址空間中,然後使用memcpy高效地將源文件內容復制到目的文件中。 點擊(此處)折疊或打開#include <stdio.h>#include <stdlib.h>#include <sys/mman.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <errno.h>#include <string.h>#include <sys/times.h>#define error(fmt,args...)\ printf(fmt, ##args);\ printf(":%s\n",strerror(errno))inline int cp_rw(int srcfd,int dstfd,char *buf,intlen);inline int cp_map(int srcfd,int dstfd,size_t len);int main(int argc,char **argv){ char buf[8192]; int srcfd,dstfd; clock_t start,end; struct tms stm,ntm; struct stat filestat; int tck; char cmdline[30];if(argc!=3) printf("usage: cmd <src> <dst>");tck=sysconf(_SC_CLK_TCK); start = times(&stm); if((srcfd=open(argv[1],O_RDONLY))==-1) { error("open %s error",argv[1]); exit(0); } if((dstfd=open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0666))==-1) { error("creat %s error",argv[2]); exit(0); } fstat(srcfd,&filestat); if(lseek(dstfd,filestat.st_size,SEEK_SET)==-1) { error("lseek error"); exit(0); } if(write(dstfd," ",1)!=1) { error("write error"); exit(0); } cp_map(srcfd,dstfd,filestat.st_size); close(srcfd); close(dstfd); end= times(&ntm); printf("copying %s to %s using cp_map:filesize=%lu MBytes Using %f seconds\n" ,argv[1],argv[2],filestat.st_size>>20,(end-start)/(double)tck);sprintf(cmdline,"rm -f %s",argv[2]); system(cmdline);return 0;}inline int cp_rw(int srcfd,int dstfd,char *buf,intlen){ int nread; while((nread=read(srcfd,buf,len))>0) { if(write(dstfd,buf,nread)!=nread) { error("write error"); return -1; } } if(nread ==-1) { error("read error"); return -1; } return 0;}inline int cp_map(int srcfd,int dstfd,size_t len){ char *src,*dst; if((src=mmap(0,len,PROT_READ,MAP_SHARED,srcfd,0))==MAP_FAILED) { error("mmap src error"); return -1; } if((dst=mmap(0,len,PROT_WRITE,MAP_SHARED,dstfd,0))==MAP_FAILED) { error("mmap dst error"); return -1; } if(memcpy(dst,src,len)==NULL) { error("memcpy error"); return -1; } munmap(src,len); munmap(dst,len); return 0;}運行,拷貝壹個1.1G的文件,得到如下結果[root@garden copy]# ./copy /home/ker.tgz ./ker.tgzcopying /home/ker.tgz to ./ker.tgz using cp_map:filesize=1030 MBytes Using 61.900000 secondscopying /home/ker.tgz to ./ker.tgz using cp_rw:filesize=1030 MBytes Using 34.330000 seconds使用read/write的方法居然比mmap的快壹倍,這是怎麽回事呢?理論上mmap系統調用只進行了壹次,而且拷貝文件是直接在內核空間進行的,read/write則需要通過系統調用把內核空間的緩存復制到用戶空間,再將用戶空間緩存復制到內核空間,拷貝次數明顯多了壹個呢?速度為什麽於理論預測的不壹致呢?

  • 上一篇:開博爾C5的開博爾C5簡介
  • 下一篇:輕NAS丨何為“輕”?老玩家談談海康G1 Master使用感受
  • copyright 2024編程學習大全網