2013-01-15 130 views
7

我有一個問題需要將結構寫入映射的內存文件。將結構寫入映射的內存文件(mmap)

我有兩個文件,即mmap.write.c和mmap.read.c,並在這些文件中,我正在寫一個整型文件並從文件中讀取它。

當我想寫結構和閱讀它,我不能去想,既然在mmap.write.c線32

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

和mmap.read.c線25

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

寫入和讀取整數/雙/浮點/字符等沒有區別,因爲我可以把模式作爲第二個參數「%d」整數。但是我會在這裏寫什麼來表示結構?這是我的主要問題。

,我要寫入和讀取的結構:

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

感謝很多提前。

回答

10

首先你要跟蹤其中在你要寫的內存中,其次你必須記住映射的內存就像其他指向內存的指針一樣。最後一位很重要,因爲這意味着您可以使用普通數組索引來訪問內存,或者使用諸如memcpy之類的函數將其複製到內存中。

自己寫的一個結構,你有三種選擇:

  1. 寫結構原樣,就像一個二進制文件。這意味着你必須將memcpy的結構移動到指定位置。

  2. 使用例如字段將結構逐字段地寫爲文本。 sprintf到正確的位置。

  3. 將內存視爲一個大字符串,然後執行將每個字段的sprintf轉換爲臨時緩衝區,然後將strcat添加到內存中。

+0

我喜歡第二種方式你提供的,簡單而容易。由於我在嵌入式系統中使用它,因此不能保證有足夠的空間。再次感謝你。 – totten

2

最簡單的方法是隻使用一個指針:

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

由於此結構不包含任何指針,如果你需要它或縮小複製,你可以爲它分配,像:

dataholder dh_other = *dh; 

*dh = dh_other; 
相關問題