您不能将“一些现有的内存缓冲区”映射到文件描述符。 正如上面评论中所说,fmemopen() 函数将内存缓冲区与“FILE *”流指针相关联,该指针可以使用 libc 提供的流函数进行操作。未分配文件描述符:“FILE *”流是高级抽象,与作为低级句柄的文件描述符不兼容。
相反,您可能希望分配一个新的共享内存缓冲区并将其映射到文件描述符。这被广泛使用,在 Linux 术语中称为“内存映射文件”。
您可以使用通过open() 获得的文件描述符来引用文件,或者使用通过shm_open() 获得的文件描述符来引用共享内存对象。任何文件描述符句柄都可以完成这项工作。然后您可以调用mmap() 将文件描述符映射到共享内存缓冲区。
注意:如果文件描述符引用非常规文件,例如管道、套接字或字符设备文件(例如,/dev/ttys001),mmap() 将失败。因此,您通常无法为 STDIN、STDOUT 或 STDERR 文件描述符创建内存映射文件。
您可以以类似数组的方式操作内存缓冲区,并将对内存映射文件的修改提交到磁盘。反之亦然,对文件所做的任何修改(例如,使用write() 系统调用)也会提交到内存。
下面的 sn -p 打开一个您选择的文件并将其映射到内存中。它将打印前 256 个字符并将它们替换为原始文件中的“*”。在符合 POSIX 的系统上使用 cc mmap_test.c -o mmap_test 编译它。
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <unistd.h>
int main(int ac, char *av[])
{
int pagesize, fd;
unsigned char *data;
if ( ac < 2 ) {
printf("Usage: %s <filepath>\n", av[0]);
return 1;
}
pagesize = getpagesize();
if ( (fd = open(av[1], O_RDWR)) == -1 ) {
perror("Error: cannot open file for reading");
return 1;
}
if ( (data = mmap(NULL, pagesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED ) {
perror("Error: cannot create memory-mapped file");
return 1;
}
write(1, data, 256);
memset(data, '*', 256);
return 0;
}