2009-06-28 9 views
6

क्या किसी को पता है कि मैं स्ट्रीम स्प्लिटर कार्यान्वयन कहां पा सकता हूं?मैं .NET में एक स्ट्रीम को कैसे कॉपी (कॉपी) कर सकता हूं?

मैं स्ट्रीम लेना चाहता हूं, और दो अलग-अलग धाराएं प्राप्त करता हूं जिन्हें स्वतंत्र रूप से पढ़ा जा सकता है और एक-दूसरे को प्रभावित किए बिना बंद किया जा सकता है। इन धाराओं में प्रत्येक एक ही द्विआधारी डेटा लौटाएगा जो मूल धारा होगी। स्थिति या खोज को कार्यान्वित करने की कोई आवश्यकता नहीं है और ऐसे ... केवल अग्रेषित करें।

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

क्या वहां कुछ भी है जो ऐसा कर सकता है?

+1

कुछ 'tee' की तरह ... –

+0

यह शायद आवश्यकता होगी एक परिपत्र बफर के आसपास आधारित किया जाना है। यदि मुझे समय मिलता है तो मैं त्वरित कार्यान्वयन लिखने की कोशिश करूंगा। – Noldorin

उत्तर

4

बॉक्स से बाहर नहीं।

आपको मूल स्ट्रीम से डेटा को फीफो तरीके से बफर करना होगा, केवल "पाठक" धाराओं द्वारा पढ़ा गया डेटा छोड़कर।

मैं का उपयोग करेंगे:

  • ए 'प्रबंधन "वस्तु बाइट की [] स्रोत धारा से हिस्सा बफ़र किए जाने की जोत और अतिरिक्त डेटा पढ़ने कतार में किसी प्रकार का धारण करता है, तो
  • कुछ आवश्यक" पाठक "उदाहरण जो जानते हैं कि वे कहां और किस बफर पर पढ़ रहे हैं, और जो" प्रबंधन "से अगले खंड का अनुरोध करते हैं और जब वे अब एक खंड का उपयोग नहीं करते हैं तो उन्हें सूचित करते हैं, ताकि इसे कतार
से हटाया जा सके
1

मुझे नहीं लगता कि आप एक पा सकेंगे ऐसा करने के लिए सामान्य कार्यान्वयन। एक स्ट्रीम बल्कि अमूर्त है, आप नहीं जानते कि बाइट कहां से आ रहे हैं। उदाहरण के लिए आप नहीं जानते कि यह मांग का समर्थन करेगा या नहीं; और आप संचालन की सापेक्ष लागत नहीं जानते हैं। (स्ट्रीम रिमोट सर्वर से डेटा पढ़ने का एक अबाध हो सकता है, या बैकअप टेप से भी!)।

यदि आप मेमोरीस्ट्रीम और सामग्री को एक बार स्टोर करने में सक्षम हैं, तो आप एक ही बफर का उपयोग करके दो अलग-अलग स्ट्रीम बना सकते हैं; और वे स्वतंत्र स्ट्रीम के रूप में व्यवहार करेंगे लेकिन केवल एक बार स्मृति का उपयोग करेंगे।

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

+0

इसका आवेदन क्या है? – headsling

1

आप वास्तव में सोर्स स्ट्रीम के कम से कम हिस्से को डुप्लिकेट किए बिना ऐसा नहीं कर सकते हैं - अधिकांशतः इस तथ्य के कारण कि यदि आपके जैसा लगता है कि वे जिस दर पर उपभोग नहीं कर रहे हैं (एकाधिक धागे?) को नियंत्रित कर सकते हैं। आप दूसरे के एक पढ़ने के बारे में कुछ चालाक कर सकते हैं (और इस प्रकार केवल उस बिंदु पर प्रतिलिपि बनाते हैं) लेकिन इस के जटिल व्यक्ति को लगता है कि यह मुसीबत के लायक नहीं है।

+0

उल्लेख नहीं है कि यदि यह एक बहु थ्रेडेड परिदृश्य में उपयोग किया जाता है तो आप ओएस/मंच को उसी फ़ाइल के एकाधिक पाठकों के लिए अपने आंतरिक तंत्र का उपयोग करने से रोकते हैं। यदि स्मृति में उपयोग किया जाता है तो सबसे खराब मामला हमेशा यह होगा कि आपको पूरी स्ट्रीम को प्रतिलिपि बनाना पड़ सकता है, इसलिए ऐसा कुछ करने की कोशिश करना संभवतः नोटिंग के लिए बहुत प्रयास है ... कई उपभोक्ताओं के मॉडल को धक्का देना बेहतर होगा – ShuggyCoUk

3

स्मृति में बफर किए गए सब कुछ को रखने के जोखिम के बिना यह मुश्किल हो सकता है (यदि स्ट्रीम क्रमशः बीओएफ और ईओएफ में हैं)।

मुझे आश्चर्य है कि क्या यह आसान डिस्क पर धारा लिखने के लिए नहीं है, यह प्रतिलिपि बनाएँ, और दो धाराओं डिस्क से पढ़ने के लिए है, स्वयं को हटाए जाने Close() में निर्मित के साथ (अर्थात अपनी खुद की Stream आवरण के आसपास FileStream बारे में)।

1

नीचे वैध EchoStream कहा जाता प्रतीत हो रहा है http://www.codeproject.com/Articles/3922/EchoStream-An-Echo-Tee-Stream-for-NET इसकी एक बहुत पुरानी कार्यान्वयन (2003) लेकिन कुछ संदर्भ

async की शुरूआत/का इंतजार है, जब तक कि साथ के माध्यम से Redirect writes to a file to a stream C#

0

पाया प्रदान करना चाहिए सब कुछ आपके पढ़ने के कार्यों में async हैं, आप केवल एक ही ओएस थ्रेड का उपयोग करके दो बार एक ही डेटा को संसाधित करने में सक्षम होना चाहिए।

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

जब आपका कस्टम स्ट्रीम कैश से ReadAsync कॉल का उत्तर दे सकता है, तो डेटा कॉपी करें, सूचक को सूची के नीचे अग्रेषित करें और वापस आएं।

जब आपका स्ट्रीम कैश सूची के अंत तक पकड़ा गया है, तो आप अंतर्निहित स्ट्रीम में एक एकल ReadAsync जारी करना चाहते हैं, बिना प्रतीक्षा किए, और डेटा ब्लॉक के साथ लौटा कार्य कैश करना चाहते हैं। तो यदि कोई अन्य स्ट्रीम रीडर भी पकड़ लेता है और इस पढ़ने को पूरा करने से पहले और अधिक पढ़ने की कोशिश करता है, तो आप एक ही कार्य वस्तु वापस कर सकते हैं।

इस तरह, दोनों पाठक एक ही ReadAsync कॉल के परिणामस्वरूप निरंतर प्रतीक्षा जारी रखेंगे। जब एकल पठन देता है, तो दोनों पढ़ने के कार्य क्रमशः उनकी प्रक्रिया के अगले चरण को निष्पादित करेंगे।

0

मैंने गिटूब और नुगेट पर स्प्लिटस्ट्रीम उपलब्ध कराया है।

यह इस तरह से चला जाता है।

using (var inputSplitStream = new ReadableSplitStream(inputSourceStream)) 

using (var inputFileStream = inputSplitStream.GetForwardReadOnlyStream()) 
using (var outputFileStream = File.OpenWrite("MyFileOnAnyFilestore.bin")) 

using (var inputSha1Stream = inputSplitStream.GetForwardReadOnlyStream()) 
using (var outputSha1Stream = SHA1.Create()) 
{ 
    inputSplitStream.StartReadAhead(); 

    Parallel.Invoke(
     () => { 
      var bytes = outputSha1Stream.ComputeHash(inputSha1Stream); 
      var checksumSha1 = string.Join("", bytes.Select(x => x.ToString("x"))); 
     }, 
     () => { 
      inputFileStream.CopyTo(outputFileStream); 
     }, 
    ); 
} 

मैंने इसे बहुत बड़ी धाराओं पर परीक्षण नहीं किया है, लेकिन इसे आज़माएं।

GitHub: UNIX में https://github.com/microknights/SplitStream

+0

बिना जवाब वास्तविक कोड स्टैक ओवरफ़्लो पर उपयोगी या वांछनीय नहीं हैं। एक अच्छा SO उत्तर पूरी तरह स्व-निहित होगा, क्योंकि यहां कुछ बाहरी संसाधनों पर पूरी तरह से निर्भर होने का विरोध किया गया है। कृपया अपना उत्तर संपादित करें ताकि पाठक उत्तर पोस्ट से सभी महत्वपूर्ण जानकारी प्राप्त कर सकें। –

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

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