求解unix中的mmap与memcpy问题
我想用mmap与memcpy两个函数实现文件的快速复制,下面是源代码:#include<stdio.h>#include<stdlib.h>#include<sys/st...
我想用mmap与memcpy两个函数实现文件的快速复制,下面是源代码:
#include<stdio.h>
#include<stdlib.h>
#include<sys/stat.h>
#include<errno.h>
#include<sys/mman.h>
#include<string.h>
#include<fcntl.h>
int main(int argc , char *argv[])
{
int fd_src, fd_des;
struct stat stat_src, stat_des;
void *addr_src, *addr_des;
if(argc != 3)
{
printf("error number of arguement!\n");
exit(-1);
}
/* 打开要复制的源文件 */
fd_src =open(argv[1], O_RDONLY);
if(fd_src == -1)
{
perror("open file error");
}
/* 打开要复制的目的文件 */
fd_des =open(argv[2], O_CREAT | O_WRONLY, 0666);
if(fd_des == -1)
{
perror("open file error");
}
/* 得到源文件的状态并创建内存映射 */
fstat(fd_src, &stat_src);
addr_src = mmap(NULL, stat_src.st_size, PROT_READ, MAP_PRIVATE, fd_src, 0);
if(addr_src == NULL)
{
perror("src mmap error!");
}
/* 改变目的文件大小 得到目的文件的状态并创建内存映射 */
lseek(fd_des, stat_src.st_size, SEEK_SET);
write(fd_des, "\0", 1);
lseek(fd_des, 0, SEEK_SET);
fstat(fd_des, &stat_des);
addr_des = mmap(NULL, stat_des.st_size, PROT_WRITE, MAP_SHARED, fd_des, 0);
if(addr_des == NULL)
{
perror("des mmap error!");
}
printf("addr_src = %u\n",addr_src);
printf("addr_des = %u\n",addr_des);
/* 内存拷贝 */
printf("copy '%s' to '%s',please waiting...\n", argv[1], argv[2]);
if(!memcpy(addr_des, addr_src, stat_src.st_size))
{
perror("mencpy error!");
}
printf("copy file successfully!\n");
/* 断开内存映射 */
if(munmap(addr_src, stat_src.st_size) == -1)
{
perror("addr_src munmap failed!");
}
if(munmap(addr_des, stat_des.st_size) == -1)
{
perror("addr_src munmap failed!");
}
close(fd_src);
close(fd_des);
}
编译得到可执行文件a.out,每次都是下面的错误
./a.out open.c hu.xx
addr_src = 3078451200
addr_des = 4294967295
copy 'open.c' to 'hu.xx',please waiting...
Segmentation fault (core dumped)
是不是文件有点大,内存不够用啊?
下面是ls 得到open.c的信息
-rw-rw-r-- 1 xxx xxx 993 8月 7 11:02 open.c 展开
#include<stdio.h>
#include<stdlib.h>
#include<sys/stat.h>
#include<errno.h>
#include<sys/mman.h>
#include<string.h>
#include<fcntl.h>
int main(int argc , char *argv[])
{
int fd_src, fd_des;
struct stat stat_src, stat_des;
void *addr_src, *addr_des;
if(argc != 3)
{
printf("error number of arguement!\n");
exit(-1);
}
/* 打开要复制的源文件 */
fd_src =open(argv[1], O_RDONLY);
if(fd_src == -1)
{
perror("open file error");
}
/* 打开要复制的目的文件 */
fd_des =open(argv[2], O_CREAT | O_WRONLY, 0666);
if(fd_des == -1)
{
perror("open file error");
}
/* 得到源文件的状态并创建内存映射 */
fstat(fd_src, &stat_src);
addr_src = mmap(NULL, stat_src.st_size, PROT_READ, MAP_PRIVATE, fd_src, 0);
if(addr_src == NULL)
{
perror("src mmap error!");
}
/* 改变目的文件大小 得到目的文件的状态并创建内存映射 */
lseek(fd_des, stat_src.st_size, SEEK_SET);
write(fd_des, "\0", 1);
lseek(fd_des, 0, SEEK_SET);
fstat(fd_des, &stat_des);
addr_des = mmap(NULL, stat_des.st_size, PROT_WRITE, MAP_SHARED, fd_des, 0);
if(addr_des == NULL)
{
perror("des mmap error!");
}
printf("addr_src = %u\n",addr_src);
printf("addr_des = %u\n",addr_des);
/* 内存拷贝 */
printf("copy '%s' to '%s',please waiting...\n", argv[1], argv[2]);
if(!memcpy(addr_des, addr_src, stat_src.st_size))
{
perror("mencpy error!");
}
printf("copy file successfully!\n");
/* 断开内存映射 */
if(munmap(addr_src, stat_src.st_size) == -1)
{
perror("addr_src munmap failed!");
}
if(munmap(addr_des, stat_des.st_size) == -1)
{
perror("addr_src munmap failed!");
}
close(fd_src);
close(fd_des);
}
编译得到可执行文件a.out,每次都是下面的错误
./a.out open.c hu.xx
addr_src = 3078451200
addr_des = 4294967295
copy 'open.c' to 'hu.xx',please waiting...
Segmentation fault (core dumped)
是不是文件有点大,内存不够用啊?
下面是ls 得到open.c的信息
-rw-rw-r-- 1 xxx xxx 993 8月 7 11:02 open.c 展开
展开全部
目标文件映射时:
addr_des = mmap(NULL, stat_des.st_size, PROT_WRITE, MAP_SHARED, fd_des, 0);
改成:
addr_des = mmap(NULL, stat_src.st_size, PROT_WRITE, MAP_SHARED, fd_des, 0);
原因:你的dst文件只是打开映射,而且只是seek并没有写操作,也没有保存,所以stat获得的大小并不是最新的。
addr_des = mmap(NULL, stat_des.st_size, PROT_WRITE, MAP_SHARED, fd_des, 0);
改成:
addr_des = mmap(NULL, stat_src.st_size, PROT_WRITE, MAP_SHARED, fd_des, 0);
原因:你的dst文件只是打开映射,而且只是seek并没有写操作,也没有保存,所以stat获得的大小并不是最新的。
更多追问追答
追问
谢谢您的回答,按您说的该了,可还是出现同样的错误,程序肯定是在memcpy函数中出错的
追答
反正我觉得那个地方文件大小有问题。dst可能还是0,除非你seek后往里写了东西。
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询