实现代码
#include#include#include#include#include //perror()
#include //exit()
#define BUFFER_SIZE 1024
int main(int argc,char *argv[])
{intfrom_fd;intto_fd;
unsignedintfile_len;int ret = 1;charbuf[BUFFER_SIZE];char *ptr;if(argc != 3)
{
printf("Usage:%s fromfile tofile\n",argv[0]);
exit(1);
}//打开源文件
from_fd = open(argv[1],O_RDONLY);if(from_fd == -1)
{
printf("open %s failed.\n",argv[1]);
exit(1);
}//以只写的方式打开文件,没有的则创建文件
to_fd = open(argv[2],O_WRONLY|O_CREAT|O_APPEND,0666); //使用0666
if(to_fd == -1)
{
printf("open %s failed.\n",argv[2]);
exit(1);
}//源文件的大小
file_len = lseek(from_fd,0,SEEK_SET); //必须重新定位offset
printf("%s size is %d bytes.\n",argv[1],file_len);while(ret)
{
ret=read(from_fd,buf,BUFFER_SIZE);if(ret == -1)
{
perror("read Error.\n");
}
write(to_fd,buf,ret);
file_len-=ret;//bzero(buf,BUFFER_SIZE);
}
printf("There are %d bytes data left without copy in %s\n",file_len,argv[1]);
close(from_fd);
close(to_fd);return 0;
}
1.注意权限必需使用0666,最好是宏
2.使用mmap操作更加高效
#include#include#include#include#include#include
int main(void)
{intlen;//打开文件,以读写的方式打开
intfd;
fd= open("hello",O_RDWR); //hello 文件存在
if(fd == -1)
{
perror("open");return -1;
}
len= lseek(fd,0L,SEEK_END);//lseek(fd,0,SEEK_SET);//将文件映射到进程的虚拟地址空间
void *p = mmap(NULL,len,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);if(p==MAP_FAILED)
{
perror("mmap");return -1;
}int *q = (int*)p;
q[0] = 0x20202020;
q[1] = 0x41414141;
munmap(p,len);
close(fd);
}
使用mmap将物理内存映射到进程的虚拟地址空间
mmap(2) 系统调用,实现代码在内核,内核态
#include
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
将文件和设备映射到进程的虚拟地址空间
Linux下一切皆文件
参数:
addr: 它指定了开始地址,在进程的虚拟地址空间里,取值为NULL,由内核决定具体的地址
length:指定了映射的区域的长度
prot:
PROT_EXEC Pages may be executed.
PROT_READ Pages may be read.
PROT_WRITE Pages may be written.
PROT_NONE Pages may not be accessed.
flags:
MAP_SHARED Share this mapping. 对映射区域的更改反映到其他进程里,同步到underlying底层文件
MAP_PRIVATE Create a private copy-on-write mapping. 对于映射区域的映射不反映到其他进程里,不同步到文件,除非msync
MAP_ANONYMOUS 匿名映射,和文件无关,映射的区域全部清为0
fd: -1
offset:文件的偏移 0
返回值:
正确:隐射区域首地址
错误:MAP_FAILED (void*)-1 errno 被设置
int munmap(void *addr, size_t length);
解除映射
addr: mmap()的返回值
length:指定了解除映射区域的长度
返回值:成功为0,错误为-1,errno被设置