【问题标题】:C/UNIX mmap array of intC/UNIX mmap int 数组
【发布时间】:2014-01-21 18:16:58
【问题描述】:

是否可以将mmap 充满整数的文件作为整数数组?我的意思是这样的(这是行不通的)

给定文件tmp.in

1 2 15 1258

和类似的代码

int fd;
if ((fd = open("tmp.in", O_RDWR, 0666)) == -1)  {
    err(1, "open");
}

size_t size =  4 * sizeof(int);
int * map = (int *) mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

我想打电话

printf("%d\n", map[2]+1);

预期结果

16

我发现使用sscanf 解析整数的字符映射,但我需要在数组中有数字(并且可能在munmap 时更改它们并保存它们)。仅使用 POSIX 函数和系统调用。

我在这里找到了 mmap reading stale array of integers from an file,但我需要文件保持可读(所以没有二进制表示)。使用strtokatoi强制我使用另一个数组,不是吗?最后,我需要将数据复制回map

感谢您的帮助:)

【问题讨论】:

    标签: c unix int mmap


    【解决方案1】:

    假设输入文件是文本文件(不是可以有整数或任何二进制数据写入其中的二进制文件),您的文件将被映射为长度等于文件大小的字符串。

    一旦这个字符串被映射到内存中,您就可以使用指针访问各个字符。

    我希望能够调用 printf("%d\n", map[2]+1);

    地图[2]+1

    这将只是增加字符的 ASCII 值。

    据我了解,您希望将文件映射到内存并更改整数等值。 只要文件是文本文件,这是不可能的。

    我的建议是将文件映射到内存中,读取字符,进行解析(在您的情况下查找空格)并更改字符值。

    这里有一个示例代码:

    [root@mohitsingh memoryMap]# cat sample.txt

    12345

    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <sys/mman.h>
    
    #define FILEPATH "./sample.txt"
    #define NUMINTS  (5)
    #define FILESIZE (NUMINTS * sizeof(int))
    
    int main(int argc, char *argv[])
    {
                    int i;
                    int fd;
                    char *map;  /* mmapped array of char */
    
                    fd = open(FILEPATH, O_RDWR);
                    if (fd == -1) {
                                                    perror("Error opening file for reading");
                                                    exit(EXIT_FAILURE);
                    }
    
                    map = mmap(0, FILESIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
                    if (map == MAP_FAILED) {
                                                    close(fd);
                                                    perror("Error mmapping the file");
                                                    exit(EXIT_FAILURE);
                    }
    
                    /* Read the file char-by-char from the mmap
                     **/
                    for (i = 0; i <NUMINTS; ++i) {
                                                    printf("%d: %c\n", i, map[i]);
                    }
                    /*change the character value
                    *Implement your own logic here to change the values as integer
                    */
                    map[2]='9';
                    if (munmap(map, FILESIZE) == -1) {
                                                    perror("Error un-mmapping the file");
                    }
                    close(fd);
                    return 0;
    }
    

    [root@mohitsingh memoryMap]# gcc test.c

    [root@mohitsingh memoryMap]# ./a.out

    0:1

    1:2

    2:3

    3:4

    4:5

    [root@mohitsingh memoryMap]# cat sample.txt

    12945

    【讨论】:

      【解决方案2】:

      不,mmap 让您自动将文件映射到您的地址空间原样。

      这意味着文本文件将被映射为字符而不是整数数组。换句话说,1 2 15 1258 将被映射(假设 ASCII 编码和 UNIX 行结尾)为:

      0x31 0x20 0x32 0x20 0x31 0x35 0x20 0x31 0x32 0x35 0x38 0x10
      

      如果您想将数据以文本形式保存在文件中,但将其二进制保存在内存中,则必须自己进行转换(双向)。

      【讨论】:

        猜你喜欢
        • 2012-06-17
        • 2011-04-16
        • 2016-04-13
        • 2012-08-24
        • 2022-01-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多