我将文件映射到String。
int fd = open(FILE_PATH, O_RDWR);
struct stat s;
int status = fstat(fd, &s);
char *f = (char*) mmap (0, s.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
然后我cJSON解析f
并进行一些修改。
cJSON *root = cJSON_Parse(f);
//some JSON operation
完成后,我从cJSON重新生成了字符串,并尝试将其写回磁盘。
char* rendered = cJSON_Print(root);
memcpy(f, rendered, strlen(rendered));
msync(f, strlen(renderer), MS_SYNC);
mmap或msync都没有错误。
我检查了文件内容,发现它正确地更改为我使用cJSON库修改的内容。
但是,文件未完成。更具体地说,它写回磁盘的大小(我使用Sublime检查)不是我放在length
msync
参数中的大小,即。 strlen(rendered)
,但是文件的原始大小,即strlen(f)
。
然后我尝试用length
512
或其他任何方式硬编码128
,但我发现所有这些都不起作用。从mmap写回文件的大小仍然是mmaped char的原始大小。
但是在msync
的手册中,它说:
对应于从addr开始并具有长度长度的内存区域的文件部分将被更新。
所以我感到困惑,任何人都可以告诉我如何分配我想要刷回磁盘的地址长度?
答案 0 :(得分:0)
感谢在评论中鼓励我的人们,抱歉,我对手册的阅读不好。
msync
无法扩展您映射的大小,也不能mmap
大小超过文件大小。
所以这就是想法:
我实现了resize_remap
功能
result_t file_remap_resize(int* fd, char** f, int new_size){
if(ftruncate(*fd, new_size) == -1){
printf("failed to resize\n");
return ERR_CODE;
}
if(munmap(*f, sizeof(*f)) == -1){
printf("failed to unmap\n");
return ERR_CODE;
}
*f = (char*)mmap (0, new_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if(!f){
printf("failed to remap\n");
return ERR_CODE;
}
return SUCCESS
}
然后程序就像:
char* rendered = cJSON_Print(root);
file_remap_resize(&fd, &f, strlen(rendered));
memcpy(f, rendered, strlen(rendered));
msync(f, strlen(renderer), MS_SYNC);
它有效!
修改后的文件可以刷回磁盘!