Запись структуры в файл сопоставленной памяти (mmap)

у меня проблема с записью struct в файл сопоставленной памяти.

у меня есть два файла, а именно через mmap.писать.c и mmap.читать.c, и в этих файлах я записываю целое число в файл и читаю его из файла.

когда я хочу написать struct и прочитать его, я не мог думать об этом, так как в строке 32 mmap.писать.c

sprintf((char*) file_memory, "%dn", i);

и в строке 25 mmap.читать.c

sscanf (file_memory, "%d", &integer);

нет никакой разницы для записи и чтения integer / double / float/char и т. д. поскольку я могу поставить pattern как второй аргумент "%d " для integer. Но что я напишу здесь, чтобы указать struct? Это моя главная проблема.

структура, которую я хочу написать и прочитать:

#define CHANNELS 20
typedef dataholder struct {
    int value[CHANNELS];
    time_t time;
    int hash;
}dataholder;

mmap.читать.c

#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#include "mmap.h"
#define FILE_LENGTH 0x10000
int main (int argc, char* const argv[])
{
    int fd;
    void* file_memory;
    int integer;
    /* Open the file. */
    fd = open (argv[1], O_RDWR, S_IRUSR | S_IWUSR);
    printf("file openedn");
    /* Create the memory mapping. */
    file_memory = mmap (0, FILE_LENGTH, PROT_READ | PROT_WRITE,
    MAP_SHARED, fd, 0);
    printf("memfile openedn");
    close (fd);
    printf("file closedn");
    /* Read the integer, print it out, and double it. */
    while(1) {
        sscanf (file_memory, "%d", &integer);
        printf ("value: %dn", integer);
        usleep(100000);
    }
    //sprintf ((char*) file_memory, "%dn", 2 * integer);
    /* Release the memory (unnecessary because the program exits). */
    munmap (file_memory, FILE_LENGTH);
    return 0;
}

mmap.писать.c

#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <time.h>
#include <unistd.h>
#include "mmap.h"
#define FILE_LENGTH 0x10000
/* Return a uniformly random number in the range [low,high]. */
int random_range (unsigned const low, unsigned const high)
{
    unsigned const range = high - low + 1;
    return low + (int) (((double) range) * rand () / (RAND_MAX + 1.0));
}
int main (int argc, char* const argv[])
{
    int fd, i;
    void* file_memory;
    /* Seed the random number generator. */
    srand (time (NULL));
    /* Prepare a file large enough to hold an unsigned integer. */
    fd = open (argv[1], O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
    //lseek (fd, FILE_LENGTH+1, SEEK_SET);
    write (fd, "", 1);
    //lseek (fd, 0, SEEK_SET);
    /* Create the memory mapping. */
    file_memory = mmap (0, FILE_LENGTH, PROT_WRITE, MAP_SHARED, fd, 0);
    close (fd);
    /* Write a random integer to memory-mapped area. */
    for(i=0; i<10000; i++) {
        sprintf((char*) file_memory, "%dn", i);
        //goto a;
        usleep(100000);
    }
    a:
    /* Release the memory (unnecessary because the program exits). */
    munmap (file_memory, FILE_LENGTH);
    return 0;
}

большое спасибо заранее.

2 ответов


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

написать структуру, у вас есть три варианта:

  1. напишите структуру как есть, как в двоичном файле файл. Это будет означать, что вы должны memcpy структура в указанное положение.

  2. напишите структуру, поле за полем, как текст, используя, например,sprintf в правильное положение.

  3. обработайте память как одну большую строку и сделайте, например,sprintf каждого поля во временный буфер, а затем strcat, чтобы добавить его в памяти.


самый простой способ-просто использовать указатель:

dataholder *dh = file_memory;
/* now you can access dh->value, dh->time, dh->hash */

поскольку эта структура не содержит никаких указателей, если вам нужно скопировать ее или удалить, вы можете просто назначить ее, например:

dataholder dh_other = *dh;

или

*dh = dh_other;