Writing a structure for a mapped memory file (mmap)

I had a problem writing a structure to a file with mapped memory.

I have two files: mmap.write.c and mmap.read.c, and in these files I write an integer to the file and read it from the file.

When I want to write a struct and read it, I could not think about it, because in line 32 mmap.write.c

sprintf((char*) file_memory, "%d\n", i); 

and in line 25 mmap.read.c

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

There is no difference in writing and reading integer / double / float / char, etc., since I can put the pattern as the second argument "% d" for the integer. But what will I write here to indicate the structure? This is my main problem.

The structure I want to write and read is:

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

mmap.read.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 opened\n"); /* Create the memory mapping. */ file_memory = mmap (0, FILE_LENGTH, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); printf("memfile opened\n"); close (fd); printf("file closed\n"); /* Read the integer, print it out, and double it. */ while(1) { sscanf (file_memory, "%d", &integer); printf ("value: %d\n", integer); usleep(100000); } //sprintf ((char*) file_memory, "%d\n", 2 * integer); /* Release the memory (unnecessary because the program exits). */ munmap (file_memory, FILE_LENGTH); return 0; } 

mmap.write.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, "%d\n", i); //goto a; usleep(100000); } a: /* Release the memory (unnecessary because the program exits). */ munmap (file_memory, FILE_LENGTH); return 0; } 

Thank you very much in advance.

+7
source share
2 answers

First of all, you need to keep track of where in the memory you want to write, and secondly, you must remember that the associated memory is like any other pointer to memory. The last bit is important, as this means that you can use the usual indexing of arrays to access memory or use memcpy functions to copy to memory.

To write a structure, you have three options:

  • Write the structure as is, as in a binary file. This will mean that the memcpy structure should be specified at the specified position.

  • Write the structure, field by field, as text, for example, sprintf in the correct position.

  • Think of memory as one big line and, for example, sprintf each field into a temporary buffer, then strcat to add it to memory.

+10
source

The easiest way is to simply use a pointer:

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

Since this structure does not contain pointers, if you need to copy or output it, you can simply assign it, for example:

 dataholder dh_other = *dh; 

or

 *dh = dh_other; 
+2
source

All Articles