2012-02-22 14 views
7

मैं जो कुछ इस तरह का उपयोग करता है कुछ विरासत कोड के साथ काम कर रहा हूँ:FILE * संरचना मानचित्र को एक बफर में बनाएं?

void store_data(FILE *file); 

हालांकि, मैं नहीं चाहता कि डिस्क पर डेटा स्टोर करना चाहते हैं, मैं स्मृति (char *buf) में संग्रहीत करना चाहते हैं। मैं सभी कोड संपादित कर सकता हूं, लेकिन कोड पूरे स्थान पर कूदता है और fwrite को पूरे स्थान पर फ़ाइल पर कॉल किया जाता है। तो क्या कोई आसान तरीका है, उदाहरण के लिए कि मैं FILE* ऑब्जेक्ट को (ऑटो-बढ़ते) बफर पर मैप कर सकता हूं? मुझे पहले डेटा के कुल आकार को नहीं पता है।

समाधान पोर्टेबल होना चाहिए।

उत्तर

5

सी मानक में प्रदान की गई सुविधाओं का उपयोग करके ऐसा करने का कोई तरीका नहीं है। निकटतम आप आ सकते हैं

FILE *scratch = tmpfile(); 
... 
store_data(scratch); 
... 
/* after you're completely done calling the legacy code */ 
rewind(scratch); 
buf = read_into_memory_buffer(scratch); 
fclose(scratch); 

है इस डिस्क को हिट करता है, कम से कम संभावित, लेकिन मैं इसे अपने सबसे अच्छे शर्त है कि अगर आप विस्तृत पोर्टेबिलिटी की जरूरत है और "विरासत कोड" संशोधित नहीं कर सकते कहना चाहते हैं।

POSIX.1-2008 में, open_memstream है, जो वास्तव में आप चाहते हैं; हालांकि, पीओएसईक्स का यह संशोधन अभी तक व्यापक रूप से अपनाया नहीं गया है। जीएनयू libc (लिनक्स और कुछ अन्य लोगों पर इस्तेमाल किया) यह है, लेकिन यह ओएसएक्स या * बीएसडी पर जहां तक ​​मुझे पता है, और निश्चित रूप से विंडोज पर उपलब्ध नहीं है।

+0

क्या पाइप शायद एक विकल्प हैं? – orlp

+0

पाइप्स सी मानक में भी नहीं हैं। यूनिक्स पर, हाँ, आप एक पाइप लूप को उसी प्रक्रिया में एक और थ्रेड पर वापस ले सकते हैं जो मेमोरी बफर को लिखा था। विंडोज़ पर, आप सैद्धांतिक रूप से एक ही काम कर सकते हैं, लेकिन मैं उम्मीद करता हूं कि यह अनजान दुःख का स्रोत बन जाएगा, और यहां तक ​​कि यूनिक्स पर भी मुझे 'tmpfile' दृष्टिकोण पर इतना अधिक लाभ नहीं मिलने के लिए बहुत अधिक काम करता है। – zwol

1

आप fmemopen और open_memstream पर देख सकते हैं। वे जो चाहते हैं उसकी दिशा में कुछ करते हैं।

आदमी पृष्ठ से:

open_memstream() फ़ंक्शन एक बफर करने के लिए लिखने के लिए एक धारा को खोलता है। बफर गतिशील रूप से आवंटित किया गया है (जैसा कि मॉलोक (3) के साथ), और automati- कैली आवश्यकतानुसार बढ़ता है। स्ट्रीम बंद करने के बाद, कॉलर मुफ्त (3) इस बफर होना चाहिए।

+1

मेरे सिस्टम पर मैन पेज के अनुसार, ये फ़ंक्शन "POSIX.1-2008" के अनुरूप हैं। ये फ़ंक्शन POSIX.1-2001 में निर्दिष्ट नहीं हैं, और अन्य सिस्टम पर व्यापक रूप से उपलब्ध नहीं हैं। " –

+0

@DanFego: सच है। – Florian

1

मैं अगर यह एक अच्छा विचार है पता नहीं है, लेकिन यह एक अच्छा विचार है।

आप एक मैक्रो का उपयोग करके fwrite "redefine" कर सकते हैं।

#define fwrite(a, b, c) your_memory_write_function(a, b, c) 

फिर memory_write_function लागू अपने ऑटो से बढ़ के बजाय बफर एक फाइल करने के लिए डेटा लिखने के लिए।

आपको किसी अन्य चीज़ के लिए store_data पर कॉल करने की आवश्यकता होगी हालांकि (FILE पर पॉइंटर नहीं)। लेकिन सी के साथ यह संभव है ताकि आपके पास कोई समस्या न हो।

0

आप fmemopen() पर देखना चाहते हैं। यदि यह आपके लिए उपलब्ध नहीं है, तो आप fdopen() के साथ shm_open() पर FILE* पर लौटाए गए फ़ाइल डिस्क्रिप्टर को परिवर्तित करने के लिए संभावित रूप से नामित साझा मेमोरी सेगमेंट का उपयोग कर सकते हैं।

+0

'fmemopen' लिखने पर मेमोरी बफर का स्वतः आकार बदलता नहीं है, इसलिए यह ओपी की आवश्यकताओं को पूरा नहीं करता है। – zwol

0

आप किस प्लेटफॉर्म पर चल रहे हैं? क्या आप tmpfs का उपयोग नहीं कर सकते? यदि आप tmpfs पर कोई फ़ाइल खोलते हैं, तो क्या यह कर्नेल के दृष्टिकोण से नहीं है, नियमित फ़ाइल के समान है, लेकिन स्मृति में लिखा गया है?

+0

कोड को __portable__ होना चाहिए, मैं किसी विशेष प्लेटफ़ॉर्म/ओएस पर नहीं चल रहा हूं (हालांकि बड़ा तीन एक अच्छी शुरुआत है)। – orlp

+0

बड़ा तीन? यह फ्रीबीएसडी, ओपनबीएसडी और नेटबीएसडी होना चाहिए, है ना? ... सही?? ... (क्रिकेट की आवाज) ... ओह, आम लोग ... – ninjalj

+0

@ निंजालज आप * इतने * एक लौ युद्ध शुरू करने के लिए देख रहे हैं। लेकिन मुझे लगता है कि यह काफी मजेदार है :- डी – mydoghasworms

संबंधित मुद्दे