读书人

linux存储映射m地图()实现文件复制

发布时间: 2013-12-10 15:05:55 作者: rapoo

linux存储映射mmap()实现文件复制
学习APUE,书里有个例程是利用linux存储映射I/O复制一个文件(类似于cp命令)


#include "apue.h"
#include <fcntl.h>
#include <sys/mman.h>

int main(int argc,char *argv[])
{
int fdin,fdout;
void *src,*dst;
struct stat statbuf;

if(argc != 3)
err_quit("usage: %s <fromfile> <tofile>",argv[0]);

if((fdin = open(argv[1],O_RDONLY)) <0)
err_sys("can't open %s",argv[1]);

if((fdout = open(argv[2],O_RDWR | O_CREAT | O_TRUNC,FILE_MODE)) < 0)
err_sys("can't creat %s for writing",argv[2]);

if(fstat(fdin,&statbuf) < 0)
err_sys("write error");

/*set size of output file*/
if(lseek(fdout,statbuf.st_size-1,SEEK_SET) == -1)
err_sys("lseek error");
if(write(fdout," ",1) != 1)
err_sys("write error");

if((src = mmap(0,statbuf.st_size,PROT_READ,MAP_SHARED,fdin,0)) == MAP_FAILED)
err_sys("mmap error for input");

if((dst = mmap(0,statbuf.st_size,PROT_READ | PROT_WRITE,MAP_SHARED,fdout,0)) ==MAP_FAILED)
err_sys("mmap error for output");

memcpy(dst,src,statbuf.st_size);
return 0;
}

我不理解的是/*set size of output file*/下面两个语句,他说这两句程序的目的是写一个字节以设置输出文件的长度,这是什么意思,输入文件的长度不是statbuf.st_size吗?那复制的输出文件长度也是statbuf.st_size啊,利用这个长度分别mmap两个存储区src和dst,然后再memcpy,长度都是statbuf.st_size啊
干嘛先设置文件偏移量,再写入一个字节,这是为什么啊?难道文件长度是statbuf.st_size-1吗?如果是statbuf.st_size-1,那直接就按statbuf.st_size-1映射、再复制不就行了?这是为什么啊?

求指点
说话比较嗦,麻烦各位耐心点,万分感激
[解决办法]
if(lseek(fdout,statbuf.st_size-1,SEEK_SET) == -1)
err_sys("lseek error");
if(write(fdout," ",1) != 1)
err_sys("write error");

这两句相当于 ftruncate(fdout, statbuf.st_size),目的是为了给fdout分配文件块,这样mmap在 shared 模式下才能正确同步内容,否则的话,mmap 映射的内存区比文件大的话,写的数据是可能丢失的。
[解决办法]
lseek是偏移,write是写。

两个动作加起来相当于pwrite。
[解决办法]
不知道直接使用 ftruncate 行不行。

读书人网 >UNIXLINUX

热点推荐