2012-03-06 16 views
5

मैं करना चाहते हैं:संदेश फ़ाइल में स्मृति बफर करने के लिए लिखते हैं (कुछ fopen, लेकिन बफ़र होना लिखते हैं, न डिस्क)

  1. रीडायरेक्ट stdout/stderr
  2. एक में स्मृति बफर करने के लिए
  3. , बल्कि जबकि छोड़ने डिस्क
  4. करने से stdout/मुझे पता है कि करने के लिए dup2 और freopen उपयोग करने के लिए के रूप में सामान्य

चल गलती:

  • रीडायरेक्ट stdout/अं मेरी
  • को चुनने का एक फाइल करने के लिए, जबकि stdout/अं सामान्य

के रूप में चल छोड़ने ... लेकिन मैं आइटम 2 के बारे में यकीन नहीं है?

कारण: मैं डेटा को स्टडआउट/गलती (जो कि तृतीय पक्ष कोड से आ रहा है) पर पोस्ट-प्रोसेस करना चाहता है, और उसके बाद इसे वेबसर्वर को भेजना है - जबकि एप्लिकेशन सामान्य के रूप में चल रहा है।

क्यों? ... क्योंकि अभी जब हमारा ऐप चलता है तो हम महत्वपूर्ण डेटा देख रहे हैं, तीसरे पक्ष कोड से stdout (और err) पर जाएं, और यह एक पिटा है जो स्थानीय लॉगफाइल के साथ उपयोगकर्ताओं को कोशिश करने और गड़बड़ करने के लिए मिलता है। मैं रिंग बफर में "अंतिम एन बाइट्स" को कैप्चर करता हूं, इसके बाद प्रक्रिया करता हूं, और फिर - अगर कोई समस्या है जो उपयोगकर्ता रिपोर्ट करता है - उसे सर्वर पर भेजें।

फाइलों से क्यों बचें? ... क्योंकि यह कोड के लिए है जिसे आईओएस के साथ-साथ डेस्कटॉप पर भी चलाना है, और "लगातार फाइल पर लिखना" कुछ ऐसा है जो मैं टालना चाहता हूं, क्योंकि मैं इसे किसी फ़ाइल के रूप में नहीं चाहता हूं। इसके अलावा ... मुझे उस फ़ाइल को बनाए रखने, इसके आकार को सक्रिय रूप से ट्रिम करने, आदि के बारे में चिंता करने की ज़रूरत होगी।

+1

आप एक पाइप का उपयोग कर सकते हैं। इस समाधान को देखें: http://stackoverflow.com/questions/955962/how-to-buffer-stdout-in-memory-and-write-it-from-a-dedicated-thread – arc

+0

कुछ यूनिक्स या पॉज़िक्स में http है : //pubs.opengroup.org/onlinepubs/9699919799/functions/fmemopen.html फ़ंक्शन (जीएनयू द्वारा प्रेरित)। जीएनयू में http://linux.die.net/man/3/open_memstream भी है, शायद आपके आईओएस में ये हैं। –

+0

ऐसा क्यों लगता है कि लोगों को पता नहीं है कि यूनिक्स सॉकेट क्या है? एक बनाएं, इसे अपने तृतीय-पक्ष stdin/stdout को डुप्लिकेट करें, इसे पोस्ट करने के लिए अपने कोड का उपयोग करें, कोई डिस्क शामिल नहीं है। – tbert

उत्तर

4

स्टडआउट एक मूल फ़ाइल हैंडल है, जिसका अर्थ है कि यह एक सूचक है।

#include <stdio.h> 
#include <stdlib.h> 

int main(int argc, char **argv); 

int main (argc,argv) 
int argc; 
char **argv; 
{ 
    stdout = &(*stderr); 
    fprintf(stdout, "test"); 
    return 0; 
} 

किसी भिन्न फ़ाइल हैंडल को इंगित करने के लिए stdout घोषित करने से, इस कार्यक्रम के लिए stdout पुनर्निर्देश। इसका परीक्षण करने के लिए, इसे test के रूप में संकलित करें, और फिर कमांड लाइन पर ./test > t और ./test 2> t टाइप करें।

पुनर्निर्देशित स्टडआउट पाइप अभी भी शब्द परीक्षण आउटपुट करेगा, जबकि पुनर्निर्देशित stderr पाइप नहीं होगा।

चूंकि फ़ाइलें स्ट्रीम हैं, इसलिए section of the GNU C Library मेमोरी स्ट्रीम बनाने के लिए पढ़ें। यह उदाहरण इनपुट धारण के लिए गतिशील रूप से आकार बदलने के लिए एक टेक्स्ट बफर बनाता है, और इसे इंगित करने के लिए stdout को पुनर्निर्देशित करता है।

#include <stdio.h> 
#include <stdlib.h> 

int main(int argc, char **argv); 

int main (argc,argv) 
int argc; 
char **argv; 
{ 
    char *bp; 
    size_t size; 
    FILE *stream; 

    stream = open_memstream (&bp, &size); 
    stdout = &(*stream); 
    fprintf(stdout, "test"); 
    fflush(stdout); 
    fprintf(stderr, "buf = %s, size = %d\n", bp, size); 
    fclose (stream); 
    free(bp); 
    return 0; 
} 

मैन्युअल में इनपुट और आउटपुट के बीच स्विच करते समय बफर को फ़्लश करने के अनुभागों पर सावधानीपूर्वक ध्यान दें।

+0

आह, धन्यवाद - ऐसा लगता है कि "मेमोरी स्ट्रीम" जादू शब्द था जिसे मुझे Google की आवश्यकता थी। मैं आईओएस के साथ इस दृष्टिकोण को आजमाउंगा और देख सकता हूं कि यह काम करता है या नहीं। फिंगर्स पार हो गए ... – Adam

+0

मैं अंत में एक 'मुक्त (बीपी)' जोड़ने का सुझाव देता हूं। इससे कोई फर्क नहीं पड़ता, लेकिन अगर कोई इसे किसी फ़ंक्शन में काट रहा है और चिपका रहा है, तो उसे इसकी आवश्यकता होगी। –

+0

@ मार्क लॉडाटो व्हाउप्स! फिक्स्ड। –

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