2011-12-27 11 views
5

मेरे पास एक ऐसा एप्लिकेशन है जो भौतिक स्मृति स्नैपशॉट्स के साथ काम करता है (उदाहरण के लिए, वीएमवेयर वीएमईएम फाइलें)। अन्य चीजों के अलावा, यह भौतिक पते के बजाय वर्चुअल द्वारा स्नैपशॉट से प्रक्रियाओं/मॉड्यूल को पढ़ सकता है। इसमें पृष्ठ तालिका के माध्यम से एक समय में मॉड्यूल 4KB का पुनर्निर्माण करना शामिल है, जो बदले में, स्ट्रीम की खोज() विधि पर कॉल के लॉट का अर्थ है।स्ट्रीम के अंतर्निहित फ़ाइल हैंडल कैसे प्राप्त करें?

कारणों से मुझे यकीन नहीं है, इन कॉलों को नाटकीय रूप से नीचे() बोग चीजों को कॉल करने के लिए कहते हैं। नतीजतन, मैं उनके चारों ओर एक रास्ता तलाश रहा हूं - या कम से कम, प्रबंधित खोज() कार्यान्वयन के आसपास एक रास्ता। मेरा सबसे अच्छा अनुमान PInvoke SetFilePointer को है और सीधे इसके साथ काम करना है, लेकिन ऐसा करने के लिए मुझे स्ट्रीम के लिए IntPtr/SafeFileHandle प्राप्त करने की आवश्यकता है।

  1. एपीआई के साथ मैं, .NET 3.5 तक ही सीमित है काम कर रहा हूँ तो दुर्भाग्य से MemoryMappedFile एक विकल्प नहीं है: मैं कुछ प्रतिबंध है।

  2. मैं स्नैपशॉट पर एक और तरीका है पाने के लिए एक FileStream (जो पहले से ही एक निजी SafeFileHandle क्षेत्र है कि प्रतिबिंब साथ पहुँचा जा सकता है) या PInvoke CreateFile() का उपयोग नहीं कर सकते हैं - एपीआई एक BinaryReader एक विशेष है कि शामिल स्नैपशॉट पर लॉक करें।

बेशक, फ़ाइलस्ट्रीम के विपरीत, न तो बाइनरी रीडर और न ही इसके अंतर्निहित स्ट्रीम में फ़ाइल हैंडल का संदर्भ है। लेकिन निश्चित रूप से एक मौजूद होना चाहिए? इस मामले में, मैं इसे प्राप्त करने के बारे में कैसे जा सकता हूं?

+1

किस तरह का 'स्ट्रीम'? सभी धाराओं में फाइल हैंडल नहीं हैं। –

+2

.NET 4.0 में MemoryMappedFile केवल देशी एपीआई के आसपास प्रबंधित रैपर है, आप 3.5 के भीतर बहुत अधिक परेशानी के बिना इसे कार्यान्वित करने में सक्षम होना चाहिए (इसलिए, मैंने पहले से ही कई कार्यान्वयन देखा है)। उसने कहा, यह मुझे लगता है कि आप ज्यादातर फाइल सिस्टम (कुछ स्मार्ट कैशिंग के अलावा) का उपयोग कर अटक गए हैं। मेमोरी मैप की गई फाइल अब तक आपको आपके वर्णित परिदृश्य में सबसे तेज़ परिणाम देता है (आउट ऑफ़ द बॉक्स उपलब्ध समाधानों की तुलना में)। – Polity

+0

@ जॉन सॉंडर्स: धन्यवाद, आपके प्रश्न ने मुझे 'बाइनरी रीडर' कक्षा पर दूसरा नजर डालने के लिए प्रेरित किया, जहां मुझे एहसास हुआ कि मुझे बस 'बेसस्ट्रीम' संपत्ति को 'फाइलस्ट्रीम' में डाउनकास्ट करने की आवश्यकता है, फिर ' SafeFileHandle'। अगर आप इसे लिखना चाहते हैं तो सही जवाब के रूप में चुनने में मुझे खुशी होगी। – Wayside

उत्तर

3

Stream के लिए कोई फ़ाइल हैंडल नहीं है क्योंकि यह एक सार वर्ग है। Stream लागू करने वाली कक्षा फ़ाइल हैंडल का उपयोग या नहीं कर सकती है - FileStream करता है, क्योंकि यह फ़ाइल से डेटा पढ़ता है, लेकिन MemoryStream, उदाहरण के लिए, नहीं।

SafeFileHandle sfh = (SafeFileHandle)typeof(FileStream).GetField("_handle", BindingFlags.NonPublic | BindingFlags.Instance).GetValue((FileStream)YOUR_BINARY_READER.BaseStream) 

एक तरफ ध्यान दें पर:: न तो प्रत्यक्ष कॉल

एक BinaryReader जिसका Stream की (इस मामले में एक SafeFileHandle में) अंतर्निहित फ़ाइल हैंडल प्राप्त करने के लिए एक FileStream, उपयोग प्रतिबिंब private SafeFileHandle _handle तक पहुँचने के लिए है, इसलिए की तरह है SetFilePointer() और न ही MemoryMappedFile इस मामले में मदद की। ऐसा लगता है कि जिस वॉल्यूम का उपयोग कर रहा हूं उस पर यादृच्छिक डिस्क एक्सेस को संभालने का कोई तेज़ तरीका नहीं है (लगातार लाखों कॉल)।

1

जब से तुम BinaryReaderFileStream से अधिक आप पाठक की BaseStream का उपयोग कर सकते है, कच्चा कि करने के लिए FileStream और फिर संभाल का उपयोग करने के अपने सार्वजनिक SafeFileHandle संपत्ति का उपयोग करें। कुछ ऐसा:

FileStream stream = (FileStream)(reader.BaseStream); 
//use stream.SafeFileHandle 
संबंधित मुद्दे