下面是一个写文件并且在子进程中读取文件并输出的例子。
踩坑点:
1.open和mmap配合使用,如果是刚新create 的文件,文件大小为0.
需要通过write给增加文件大小,lseek可以通过移动seek指针配合write增加文件大小。
2.在mmap的时候一定要设置MAP_SHARED或者MAP_PRIVATE,否则的话会出错。
#include <cstdio>
#include <sys/mman.h>
#include <cstring>
#include <iostream>
#include <sys/wait.h>
#include <fcntl.h>
#include <unistd.h>
#include<sys/stat.h>
// 使用mmap读写文件
using namespace std;
int main() {
int fd = open("./my_rw4.txt", O_CREAT | O_TRUNC|O_RDWR,0664);
if(fd<0){
perror("File not open");
return 0;
}
struct stat state;
// 获取文件的信息
if(fstat(fd,&state)==-1){
perror("fstat failed.");
close(fd);
return 0;
}
const char* ptr="This is the file.";
lseek(fd,strlen(ptr)-1,SEEK_END);
printf("The size of file: %d bytes.\n",state.st_size);
write(fd,"",1);
// if(ftruncate(fd,17456)==-1){
// perror("Error setting file size");
// close(fd);
// return 1;
// }
if(fstat(fd,&state)==-1){
perror("fstat failed.");
close(fd);
return 0;
}
printf("The size of file: %d bytes.\n",state.st_size);
char *addr = (char*)mmap(nullptr, strlen(ptr), PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, fd, 0);
if(addr==MAP_FAILED){
perror("map failed.");
close(fd);
return 0;
}
// extern char* ptr="This is the file.";
strcpy(addr,ptr);
cout<<addr<<endl;
if (msync(addr, strlen(ptr), MS_SYNC) == -1) {
perror("Error synchronizing mapping to disk");
// 处理错误
}
munmap(addr,strlen(addr));
// 读取文件
// 在子进程中读取文件
if (fork() == 0) {
close(fd);
cout<<strlen(ptr)<<endl;
int fd_child=open("./my_rw4.txt", O_RDONLY);
if(fd_child<0){
perror("File not open");
return 0;
}
char* addr_child=(char*)mmap(nullptr,strlen(ptr),PROT_READ,MAP_FILE|MAP_SHARED,fd_child,0);
if(addr_child==MAP_FAILED){
perror("map failed.");
close(fd_child);
return 0;
}
cout<<(char*)addr_child<<endl;
// *(int *)addr = 2333;
// printf("val in process %d is %d.\n", getpid(), *(int *)addr);
munmap(addr_child, strlen((char*)addr_child));
close(fd_child);
exit(0);
}
wait(nullptr);
// printf("val in process %d is %d.\n", getpid(), *(int *)addr);
// munmap(addr, 4);
close(fd);
return 0;
}
使用truncate可以增加文件大小,如下:
#include <fcntl.h>
#include <unistd.h>
#include <cstdio>
#include <sys/mman.h>
#include <cstring>
#include <iostream>
#include <sys/wait.h>
#include <fcntl.h>
#include <unistd.h>
#include<sys/stat.h>
int main() {
int fd = open("example.txt", O_CREAT | O_RDWR, 0664);
if (fd == -1) {
perror("Error opening/creating file");
return 1;
}
// 设置文件大小为 4096 字节
if (ftruncate(fd, 4096) == -1) {
perror("Error setting file size");
close(fd);
return 1;
}
// 在这里可以进行对文件的操作,比如使用 mmap 映射到内存
// 关闭文件
close(fd);
return 0;
}
下面是一个使用mmap读取文件的用法:
#include <cstdio>
#include <sys/mman.h>
#include <cstring>
#include <iostream>
#include <sys/wait.h>
#include <fcntl.h>
#include <unistd.h>
#include<sys/stat.h>
// 使用mmap读写文件
using namespace std;
int main() {
struct stat state;
int fd_child=open("./my_rw4.txt", O_RDONLY);
if(fd_child<0){
perror("File not open");
return 0;
}
fstat(fd_child,&state);
cout<<state.st_size<<endl;
// 获取的文件大小是正确的
char* addr_child=(char*)mmap(nullptr,state.st_size,PROT_READ,MAP_FILE|MAP_PRIVATE,fd_child,0);
if(addr_child==MAP_FAILED){
perror("map failed.");
close(fd_child);
return 0;
}
cout<<(char*)addr_child<<endl;
// *(int *)addr = 2333;
// printf("val in process %d is %d.\n", getpid(), *(int *)addr);
munmap(addr_child, strlen((char*)addr_child));
close(fd_child);
exit(0);
return 0;
}