c - msync的 'length`参数不起作用

标签 c linux mmap

我将文件映射到字符串。

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 检查它)不是我在 msynclength 参数中输入的大小,即strlen(rendered),但文件的原始大小,即 strlen(f)

然后我尝试通过 512 128 或其他方式硬编码分配 length,但我发现它们都不起作用。从 mmap 回写到文件的大小仍然是 mmaped 字符的原始大小。

但是在msync的手册中,它说:

The part of the file that corresponds to the memory area starting at addr and having length length is updated.

所以我感到很困惑,谁能告诉我如何分配要刷新回磁盘的地址长度?

最佳答案

感谢那些在评论中鼓励我的人,抱歉我没有仔细阅读手册。

msync 无法扩展您映射的大小,您也不能mmap 大于文件大小。

所以这里是想法:

  1. 增加文件大小
  2. 取消映射
  3. 重新映射
  4. 将重新映射的 f 与新内容同步

在那里我实现了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);

而且有效!

修改后的文件可以刷新回磁盘!

关于c - msync的 'length`参数不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44518899/

相关文章:

linux - 每个镜像的 Raspberry Pi 安装程序

c++ - Shmem vs tmpfs vs mmap

c - 通过mmap写入文件,但是当我使用fread时,第二次读取错误数据

python - 如何使用 gcc 编译和链接 python3 包装函数

c - C 中的内联 vector 运算

linux - 在不使用任何预定义函数和使用 shell 脚本的情况下为 diff 输出着色

solaris - mmap会使用连续内存吗? (在 Solaris 上)

android - 如何使用 perror() 但将提示输出到文件

c - 如何在 C 中通过 SSL 使用 POP3

java - 如何使用所有文件之间的 shell 脚本计算一些值,以便输出是所有矩阵?