2013-01-15 14 views
7

पर स्ट्रेटिंग स्ट्रक्चर को मैप किए गए मेमोरी फ़ाइल में स्ट्रक्चर लिखने में समस्या है।मैप किए गए मेमोरी फ़ाइल (एमएमएपी)

मेरे पास दो फ़ाइल हैं mmap.write.c और mmap.read.c, और इन फ़ाइलों में, मैं एक फ़ाइल को एक पूर्णांक लिख रहा हूं और इसे फ़ाइल से पढ़ रहा हूं।

जब मैं struct लिख सकते हैं और इसे पढ़ने के लिए चाहते हैं, तो मैं mmap.write.c की लाइन 32 में के बाद से उस के बारे में नहीं सोच सकता है

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

और mmap.read.c की लाइन 25 में

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

पूर्णांक/डबल/फ्लोट/चार इत्यादि लिखने और पढ़ने में कोई अंतर नहीं है क्योंकि मैं पूर्णांक के लिए पैटर्न को "% d" के रूप में रख सकता हूं। लेकिन संरचना को इंगित करने के लिए मैं यहां क्या लिखूंगा? यह मेरी मुख्य समस्या है।

struct है कि मैं लिख सकते हैं और पढ़ना चाहते हैं:

#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 */ 

के बाद से इस struct किसी भी संकेत दिए गए हैं, अगर आप या बाहर में इसे कॉपी करने की जरूरत है, तो आप सिर्फ यह निर्दिष्ट कर सकते हैं शामिल नहीं है, जैसे:

dataholder dh_other = *dh; 

या

*dh = dh_other; 
संबंधित मुद्दे