Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从五个I/O C/C读取的内存映射+;_C_Io_Memory Mapped Files - Fatal编程技术网

从五个I/O C/C读取的内存映射+;

从五个I/O C/C读取的内存映射+;,c,io,memory-mapped-files,C,Io,Memory Mapped Files,我是内存映射领域的新手,我想知道是否有任何方法可以使用映射到字符串的内存读取文本文件。我真的不知道如何开始编写代码。内存映射I/O的一般想法是,您告诉操作系统(OS)您想要什么文件,它(在做了一些设置工作后)会告诉您该文件现在在内存中的位置 一旦该契约被执行,您应该能够以您希望的任何方式(例如使用memcpy)在该内存中复制内容,它将神奇地为您处理I/O 细节取决于您使用的操作系统,因为ISO C标准没有规定这种行为——因此它是特定于操作系统的 例如,Windows使用如图所示的文件映射范例,而

我是内存映射领域的新手,我想知道是否有任何方法可以使用映射到字符串的内存读取文本文件。我真的不知道如何开始编写代码。

内存映射I/O的一般想法是,您告诉操作系统(OS)您想要什么文件,它(在做了一些设置工作后)会告诉您该文件现在在内存中的位置

一旦该契约被执行,您应该能够以您希望的任何方式(例如使用
memcpy
)在该内存中复制内容,它将神奇地为您处理I/O

细节取决于您使用的操作系统,因为ISO C标准没有规定这种行为——因此它是特定于操作系统的

例如,Windows使用如图所示的文件映射范例,而Linux使用允许您对已打开的文件进行内存映射(通过其文件描述符)

举个例子,这个Linux程序有点大,主要是因为它的错误检查和进度报告,内存映射
file.txt
文件并输出其内容:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>

// Helper function to minimise error code in main.

static int clean(
    int retVal,     // value to return.
    char *err,      // error/NULL, allows optional %s for strerror(errno).
    int fd,         // fd/-1 to close.
    void *filMem,   // memory/NULL to unmap.
    off_t sz,       // size if unmapping.
    void *locMem    // memory/NULL to free.
) {
    if (err)     printf (err, strerror(errno));
    if (locMem)  free(locMem);
    if (filMem)  munmap(filMem, sz);
    if (fd >= 0) close(fd);
    return retVal;
}

int main(void) {
    int fd = open("file.txt", O_RDONLY);
    if (fd < 0) return clean(-1, "Can't open: %s\n", -1, NULL, 0, NULL);
    printf("File opened okay, fd = %d.\n", fd);

    off_t sz = lseek(fd, 0, SEEK_END);
    if (sz == (off_t) -1) return clean(-1, "Can't seek: %s\n", fd, NULL, 0, NULL);
    printf("File size is %ld.\n", sz);

    void *fileArea = mmap(NULL, sz, PROT_READ, MAP_SHARED, fd, 0);
    if (! fileArea) return clean(-1, "Can't map: %s\n", fd, NULL, 0, NULL);
    printf("File mapped to address %p.\n", fileArea);

    char *localArea = calloc(1, sz + 1);
    if (! localArea) return clean(-1, "Can't allocate\n", fd, fileArea, sz, NULL);
    memcpy(localArea, fileArea, sz);
    printf("Data copied to %p, result is [\n%s]\n", localArea, localArea);

    return clean(0, NULL, fd, fileArea, sz, localArea);
}

C字符串以0字节结尾,这与大多数文件不同。但是,如果您像任何其他数组一样跟踪内存的长度,并且在末尾不使用sentinel值,那么当然可以。
off\t sz=lseek(fd,0,SEEK\u end)?如果您已经在使用POSIX
open()
mmap()
,只需在打开的文件描述符上使用
fstat()
即可获得文件大小。
pax$ cat file.txt
...This is the input file content.

pax$ ./testprog
File opened okay, fd = 3.
File size is 35.
File mapped to address 0x7f868a93b000.
Data copied to 0x1756420, result is [
...This is the input file content.
]