example c file io mmap

example - Escribiendo struct en el archivo de memoria mapeado(mmap)



mmap c (2)

En primer lugar, debe hacer un seguimiento de la memoria que desea escribir, segundo, debe recordar que la memoria mapeada es como cualquier otro puntero a la memoria. El último bit es importante, ya que esto significa que puede utilizar la indexación de matriz normal para acceder a la memoria, o utilizar funciones como memcpy para copiar en la memoria.

Para escribir una estructura, tienes tres opciones:

  1. Escribe la estructura tal como está, como en un archivo binario. Esto significará que tiene que memcpy la estructura a una posición especificada.

  2. Escriba la estructura, campo por campo, como texto usando, por ejemplo, sprintf en la posición correcta.

  3. Trate la memoria como una cadena grande, y haga, por ejemplo, sprintf de cada campo en un buffer temporal, luego strcat para agregarlo a la memoria.

Tengo un problema para escribir struct en un archivo de memoria mapeado.

Tengo dos archivos, a saber, mmap.write.c y mmap.read.c, y en estos archivos, estoy escribiendo un número entero en un archivo y lo leo desde el archivo.

Cuando quiero escribir struct y leerlo, no puedo pensar en eso desde la línea 32 de mmap.write.c

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

y en la línea 25 de mmap.read.c

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

No hay diferencia para escribir y leer entero / doble / flotante / char, etc. ya que puedo poner el patrón como segundo argumento "% d" para entero. ¿Pero qué voy a escribir aquí para indicar struct? Ese es mi principal problema.

La estructura que quiero escribir y leer:

#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; }

Muchas gracias por adelantado.


La forma más sencilla es usar un puntero:

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

Como esta estructura no contiene punteros, si necesita copiarla o sacarla, simplemente puede asignarla, como:

dataholder dh_other = *dh;

o

*dh = dh_other;