gpt4 book ai didi

c - 内存映射文件

转载 作者:行者123 更新时间:2023-12-02 05:24:50 25 4
gpt4 key购买 nike

我编写了一个代码,用于将内容写入使用 mmap() 系统调用映射的映射缓冲区。
在映射缓冲区中做了一些更改之后,我调用了 msync()。它应该更新到磁盘上的文件。

但是,它没有对磁盘上的文件进行任何更改。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include<sys/mman.h>
#include<fcntl.h>
#define FILEMODE S_IRWXU | S_IRGRP | S_IROTH
#define MAX 150

main(int argc,char *argv[])
{
int fd,ret,len;
long int len_file;
struct stat st;
char *addr;
char buf[MAX];


if(argc > 1)
{
if((fd = open(argv[1],O_RDWR | O_APPEND | O_CREAT ,FILEMODE)) < 0)
perror("Error in file opening");

if((ret=fstat(fd,&st)) < 0)
perror("Error in fstat");

len_file = st.st_size;

/*len_file having the total length of the file(fd).*/


if((addr=mmap(NULL,len_file,PROT_READ|PROT_WRITE,MAP_PRIVATE,fd,0)) == MAP_FAILED)
perror("Error in mmap");

len = len_file;

while((fgets(buf,MAX,stdin)) != NULL)
{
strcat(addr+len,buf);
printf( "Val:%s\n",addr ) ; //Checking purpose
len = len + (strlen(buf));
}
if((msync(addr,len,MS_SYNC)) < 0)
perror("Error in msync");

if( munmap(addr,len) == -1)
printf("Error:\n");
printf("addr %p\n",addr);
}
else
{
printf("Usage a.out <filename>\n");
}
}

最佳答案

如果您希望您的更改反射(reflect)在磁盘文件中,您必须将该文件映射为 MAP_SHARED ,不是 MAP_PRIVATE .

此外,您不能简单地通过在映射末尾之外写入来扩展文件。您必须使用 ftruncate()将文件扩展到新大小,然后更改映射以包含文件的新部分。更改映射的可移植方式是取消映射,然后使用新大小重新创建;在 Linux 上,您可以改为使用 mremap() .

您的 lenlen_file变量的类型应该是 size_t , 你应该使用 memcpy()而不是 strcat() ,因为您确切知道字符串的长度,确切地知道要复制它的位置,并且不想复制空终止符。

您的代码的以下修改适用于 Linux(使用 mremap()):

#define _GNU_SOURCE
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include<sys/mman.h>
#include<fcntl.h>
#define FILEMODE S_IRWXU | S_IRGRP | S_IROTH
#define MAX 150

int main(int argc,char *argv[])
{
int fd, ret;
size_t len_file, len;
struct stat st;
char *addr;
char buf[MAX];

if (argc < 2)
{
printf("Usage a.out <filename>\n");
return EXIT_FAILURE;
}

if ((fd = open(argv[1],O_RDWR | O_CREAT, FILEMODE)) < 0)
{
perror("Error in file opening");
return EXIT_FAILURE;
}

if ((ret = fstat(fd,&st)) < 0)
{
perror("Error in fstat");
return EXIT_FAILURE;
}

len_file = st.st_size;

/*len_file having the total length of the file(fd).*/

if ((addr = mmap(NULL,len_file,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0)) == MAP_FAILED)
{
perror("Error in mmap");
return EXIT_FAILURE;
}

while ((fgets(buf,MAX,stdin)) != NULL)
{
len = len_file;
len_file += strlen(buf);
if (ftruncate(fd, len_file) != 0)
{
perror("Error extending file");
return EXIT_FAILURE;
}
if ((addr = mremap(addr, len, len_file, MREMAP_MAYMOVE)) == MAP_FAILED)
{
perror("Error extending mapping");
return EXIT_FAILURE;
}
memcpy(addr+len, buf, len_file - len);
printf( "Val:%s\n",addr ) ; //Checking purpose
}
if((msync(addr,len,MS_SYNC)) < 0)
perror("Error in msync");

if (munmap(addr,len) == -1)
perror("Error in munmap");

if (close(fd))
perror("Error in close");

return 0;
}

关于c - 内存映射文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8411709/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com