C/UNIX mmap массив int

Это возможно 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 читает устаревший массив целых чисел из файла, но мне нужно, чтобы файл оставался читаемым (поэтому нет двоичного представления). С помощью strtok а также atoiзаставляет меня использовать другой массив, не так ли? В конце мне нужно будет скопировать мои данные обратно в map,

Спасибо за помощь:)

2 ответа

Решение

Нет, mmap дает вам автоматическое отображение файла в ваше адресное пространство как есть.

Это означает, что текстовый файл будет отображаться как символы, а не как массив целых чисел. Другими словами, 1 2 15 1258 будет отображаться (при условии кодирования ASCII и окончания строк UNIX) как:

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

Если вы хотите сохранить данные как текстовые в файле, но иметь двоичные данные в памяти, вам придется конвертировать их самостоятельно (в обоих направлениях).

Предполагая, что входным файлом является текстовый файл (не двоичный файл, который может иметь целое число или, в этом отношении, любые двоичные данные, записанные в него), ваш файл будет отображен как строка, длина которой равна размеру файла.

Как только эта строка отображается в памяти, вы можете получить доступ к отдельным персонажам с помощью указателей.

Я хотел бы иметь возможность вызывать 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

Другие вопросы по тегам