2009-05-29 5 views
5

में एक बाइनरी फ़ाइल कैशिंग करना क्या .NET में एक बाइनरी फ़ाइल कैश करना और कैश की गई फ़ाइल पर सामान्य फ़ाइल ऑपरेशन करना संभव है?सी #

+2

हू? 1) कैश से आपका क्या मतलब है? 2) बाइनरी फ़ाइल (उदा। गैर पाठ फ़ाइल, निष्पादन योग्य, छवि)? 3) "सामान्य फ़ाइल" संचालन? –

+1

इसके अलावा आप इसे कैश करना क्यों चाहते हैं? शायद यह अनावश्यक है? – uriDium

+0

कृपया उपयोग केस का उपयोग करें। –

उत्तर

11

ऐसा करने का तरीका FileStream से MemoryStream ऑब्जेक्ट में संपूर्ण सामग्री को पढ़ने के लिए है, और फिर बाद में I/O के लिए इस ऑब्जेक्ट का उपयोग करें। दोनों प्रकार Stream से प्राप्त होते हैं, इसलिए उपयोग प्रभावी रूप से समान होगा।

यहाँ एक उदाहरण है:

private MemoryStream cachedStream; 

public void CacheFile(string fileName) 
{ 
    cachedStream = new MemoryStream(File.ReadAllBytes(fileName)); 
} 

तो बस CacheFile विधि एक बार कहीं और कोड उपयोग cachedStream में पढ़ने के लिए फोन जब आप दिए गए फ़ाइल कैश करने के लिए चाहते हैं और फिर। (जैसे ही इसकी सामग्री कैश की गई थी, वास्तविक फ़ाइल बंद कर दी जाएगी।) याद रखने के लिए केवल cachedStream का निपटान करना है जब आप इसके साथ समाप्त हो जाते हैं।

+3

+1: मुझे लगता है कि यह वास्तव में पूछताछकर्ता क्या चाहता है। –

+0

यह शायद ठीक रहेगा - एकमात्र मुद्दा होगा यदि हम उस फाइल के बारे में बात कर रहे हैं जिसमें जीबी या दो का आकार है। –

+2

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

3

किसी भी आधुनिक ओएस में एक कैशिंग सिस्टम बनाया गया है, इसलिए वास्तव में जब भी आप किसी फ़ाइल से बातचीत करते हैं, तो आप फ़ाइल के इन-मेमोरी कैश से बातचीत कर रहे हैं।

कस्टम कैशिंग लागू करने से पहले, आपको एक महत्वपूर्ण प्रश्न पूछने की आवश्यकता है: अंतर्निहित फ़ाइल में परिवर्तन होने पर क्या होता है, इसलिए मेरी कैश की गई प्रति अमान्य हो जाती है?

कैश की गई प्रतिलिपि बदलने की अनुमति देने पर आप मामलों को और जटिल कर सकते हैं, और परिवर्तनों को अंतर्निहित फ़ाइल में वापस सहेजने की आवश्यकता है।

यदि फ़ाइल छोटी है, तो MemoryStream का उपयोग किसी अन्य उत्तर में सुझाए जाने के लिए आसान है।

यदि आपको फ़ाइल में बदलावों को वापस सहेजने की आवश्यकता है, तो आप एक रैपर वर्ग लिख सकते हैं जो आगे की ओर MemoryStream पर सबकुछ लिख सकता है, लेकिन अतिरिक्त रूप से एक IsDirty प्रॉपर्टी है जो किसी भी लिखने के ऑपरेशन के दौरान सत्य पर सेट होती है। फिर आपके पास कुछ प्रबंधन कोड हो सकता है जो जब भी आप चुनते हैं (कुछ बड़े लेनदेन के अंत में) में, (IsDirty == true) के लिए चेक करता है और डिस्क पर नया संस्करण सहेजता है। इसे "आलसी लेखन" कैशिंग कहा जाता है, क्योंकि संशोधनों को स्मृति में बनाया जाता है और वास्तव में कुछ समय बाद तक सहेजा नहीं जाता है।

यदि आप वास्तव में मामलों को जटिल करना चाहते हैं, या आपके पास बहुत बड़ी फ़ाइल है, तो आप अपनी खुद की पेजिंग को कार्यान्वित कर सकते हैं, जहां आप बफर आकार (शायद 1 एमबी?) चुनते हैं और उस निश्चित के byte[] पृष्ठों की एक छोटी संख्या रखते हैं आकार। इस बार आप प्रत्येक पृष्ठ के लिए एक गंदे झंडा होगा। आप स्ट्रीम विधियों को लागू करेंगे ताकि वे कॉलर से ब्योरा छिपा सकें, और जब भी आवश्यक हो तो पेज बफर को खींचें (या त्यागें)।

अंत में, यदि आप एक आसान जीवन चाहते हैं, की कोशिश:

http://www.microsoft.com/Sqlserver/2005/en/us/compact.aspx

यह आप सब कुछ अपनी प्रक्रिया के अंदर हो के बजाय एक के माध्यम से, एसक्यूएल सर्वर के रूप में, लेकिन एक फ़ाइल पर एक ही एसक्यूएल इंजन का उपयोग करने देता बाहरी आरडीबीएमएस सर्वर। यह आपको आपकी फ़ाइल को क्वेरी करने और अपडेट करने का एक आसान तरीका देगा, और बहुत से हाथ से लिखे दृढ़ता कोड की आवश्यकता से बचें।

+0

क्या यह स्मृति-मैप की गई फ़ाइल (http://en.wikipedia.org/wiki/Memory-mapped_file) नहीं है? फिर भी, मैं टंक करता हूं कि ओपी जितनी जल्दी हो सके फ़ाइल हैंडल को बंद करना चाहता है। – Noldorin

+0

एक फ़ाइल मेमोरी-मैपिंग वह जगह है जहां ओएस प्रक्रिया की पता स्थान के किसी क्षेत्र के लिए वर्चुअल मेमोरी बैकिंग स्टोर प्रदान करने के लिए फ़ाइल (आपकी पसंद का) उपयोग करता है। (पृष्ठ फ़ाइल सामान्य रूप से आवंटन स्मृति के लिए इस उद्देश्य की सेवा करती है।) मैं इस तथ्य के बारे में बात कर रहा हूं कि ओएस में डिस्क कैशिंग है जो इस पर निर्भर करता है कि आप फ़ाइल तक कैसे पहुंचते हैं। Grep का उपयोग करने की कोशिश करें या कुछ सौ एमबी पाठ फ़ाइलों को खोजने के समान। दूसरी बार जब आप इसे करते हैं, तो यह बहुत तेज़ होगा और आपकी हार्ड ड्राइव ध्वनि नहीं करेगी, क्योंकि यह सब स्मृति में है। –

+0

@ एरविकर: हाँ, मुझे यकीन है कि आप सही हैं। फिर भी, मेमोरीस्ट्रीम में सामग्री को कॉपी करना सबसे अच्छा समाधान प्रतीत होता है क्योंकि ए) यह फ़ाइल पर लॉक बनाए नहीं रखता है b) मुझे संदेह है कि यह अभी भी प्रदर्शन लाभ प्रदान करेगा। – Noldorin

3

ठीक है, आप निश्चित रूप से फ़ाइल को बाइट [] सरणी में पढ़ सकते हैं और उस पर काम करना शुरू कर सकते हैं। और अगर आप एक धारा का उपयोग करने की एक MemoryStream में अपने FileStream कॉपी कर सकते हैं और इसके साथ काम शुरू करना चाहते हैं - जैसे: - अलग फ़ाइल की अच्छी तरह से, सामान्य रूप से निर्माण में तंत्र

public static void CopyStream(Stream input, Stream output) 
{ 
     var buffer = new byte[32768]; 
     int readBytes; 
     while((readBytes = input.Read(buffer, 0, buffer.Length)) > 0) 
     { 
       output.Write(buffer, 0, readBytes); 
     } 
} 

आप प्रदर्शन के बारे में चिंतित हैं, तो पहुंच तरीकों पर्याप्त होना चाहिए।

0

मैं तुम्हें वास्तव में क्या कर रहे हैं पता नहीं है, लेकिन मैं इस सुझाव की पेशकश (जो कर सकते हैं या आप क्या कर रहे हैं पर निर्भर करता व्यवहार्य नहीं हो सकता है):

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

+0

फ़ाइल में बहुत सारे रिकॉर्ड हैं। यह वास्तव में अधिकतम देश डेटाबेस डेटाबेस बाइनरी फ़ाइल –

+0

है, क्या हम यह मान सकते हैं कि वास्तविक समस्या यह है कि आपको अपने प्रश्नों से प्रदर्शन नहीं मिल रहा है? –

0

Lucene में एक बहुत ही सुरुचिपूर्ण कैशिंग सिस्टम है जो डिस्क से बाइट को स्मृति में कैश करता है और समझदारी से स्टोर को अपडेट करता है। आप उस कोड को देखना चाहते हैं कि वे इसे कैसे करते हैं। आप माइक्रोसॉफ्ट एसक्यूएल सर्वर डेटा स्टोरेज लेयर पर भी पढ़ना चाहेंगे - क्योंकि एमएसएसएलएल टीम कुछ महत्वपूर्ण कार्यान्वयन विवरणों के बारे में काफी आगामी है।