gpt4 book ai didi

c - 如何使用 C 的 mmap() 更改文本文件中的字符?

转载 作者:行者123 更新时间:2023-12-04 00:10:49 25 4
gpt4 key购买 nike

假设我将标准的“Hello, World!\n”保存到名为 hello.txt 的文本文件中。如果我想将“H”更改为“R”或其他内容,我可以使用 mmap() 实现吗?

最佳答案

mmap 不存在于标准 C99(或 C11)规范中。它是在 POSIX 中定义的。

所以假设你有一个 POSIX 系统(例如 Linux),你可以先 open(2)读写文件:

int myfd = open("hello.txt", O_RDWR);
if (myfd<0) { perror("hello.txt open"); exit(EXIT_FAILURE); };

然后你用 fstat(2) 得到文件的大小(和其他元数据) :

struct stat mystat = {};
if (fstat(myfd,&mystat)) { perror("fstat"); exit(EXIT_FAILURE); };

现在文件的大小在 mystat.st_size 中。

off_t myfsz = mystat.st_size;

现在我们可以调用mmap(2)我们需要分享 mapping (能够通过 virtual address space 写入文件内部)

void*ad = mmap(NULL, myfsz, PROT_READ|PROT_WRITE, MAP_SHARED, 
myfd, 0);
if (ad == MMAP_FAILED) { perror("mmap"); exit(EXIT_FAILURE); };

然后我们可以覆盖第一个字节(并且我们检查该文件中的第一个字节确实是 H,因为你 promise 如此):

assert (*(char*ad) == 'H');
((char*)ad) = 'R';

我们可能会调用 msync(2)以确保文件立即在磁盘上更新。如果我们不这样做,它可能会在以后更新。

特别是对于非常大的映射(特别是那些比可用 RAM 大得多的映射),我们可以通过 page cache 给出的提示来帮助内核(及其 madvise(2) )或 posix_madvise(3) ...

请注意,即使在 close(2) 之后映射仍然有效.在同一地址范围内使用 munmapmprotectmmapMAP_FIXED 来更改它们。

在 Linux 上,您可以使用 proc(5)查询地址空间。因此您的程序可以读取(例如,在 fopen 之后,在循环中使用 fgets)伪 /proc/self/maps 文件(或 /proc/1234/maps 用于 pid 1234 的进程)。

顺便说一句,mmapdlopen(3) 使用;可以叫很多次,我的manydl.c程序演示了在 Linux 上您可以拥有数十万个 dlopen 共享文件(如此之多的内存映射)。

关于c - 如何使用 C 的 mmap() 更改文本文件中的字符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35859545/

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