जवाबों:
एक धारा वस्तुओं के अनुक्रम का प्रतिनिधित्व करती है (आमतौर पर बाइट्स, लेकिन जरूरी नहीं कि ऐसा हो), जिसे अनुक्रमिक क्रम में पहुँचा जा सकता है। एक धारा पर विशिष्ट संचालन:
एक विशेष स्ट्रीम पढ़ने का समर्थन कर सकती है (जिस स्थिति में यह "इनपुट स्ट्रीम" है), लेखन ("आउटपुट स्ट्रीम") या दोनों। सभी धाराएँ खोजी नहीं हैं।
पुश बैक काफी दुर्लभ है, लेकिन आप वास्तविक इनपुट स्ट्रीम को एक अन्य इनपुट स्ट्रीम में लपेटकर एक धारा में जोड़ सकते हैं जो आंतरिक बफर रखती है। रीड बफर से आते हैं, और यदि आप पीछे धकेलते हैं तो डेटा को बफर में रखा जाता है। यदि बफर में कुछ भी नहीं है, तो पुश बैक स्ट्रीम वास्तविक स्ट्रीम से पढ़ता है। यह एक "स्ट्रीम एडेप्टर" का एक सरल उदाहरण है: यह एक इनपुट स्ट्रीम के "अंत" पर बैठता है, यह एक इनपुट स्ट्रीम ही है, और यह कुछ अतिरिक्त करता है जो मूल स्ट्रीम नहीं करता था।
स्ट्रीम एक उपयोगी अमूर्त है क्योंकि यह फाइलों का वर्णन कर सकता है (जो वास्तव में सरणियां हैं, इसलिए इसकी तलाश सीधी है) लेकिन टर्मिनल इनपुट / आउटपुट (जो कि जब तक कि बफर नहीं है), सॉकेट्स, सीरियल पोर्ट्स इत्यादि भी हैं, इसलिए आप कोड लिख सकते हैं जो कहता है या तो "मुझे कुछ डेटा चाहिए, और मुझे परवाह नहीं है कि यह कहाँ से आता है या यह यहाँ कैसे मिला", या "मैं कुछ डेटा का उत्पादन करूँगा, और यह पूरी तरह से मेरे कॉलर पर निर्भर है कि इसका क्या होता है"। पूर्व इनपुट स्ट्रीम पैरामीटर लेता है, बाद वाला आउटपुट स्ट्रीम पैरामीटर लेता है।
सबसे अच्छा सादृश्य मैं यह सोच सकता हूं कि एक धारा एक कन्वेयर बेल्ट है जो आपकी ओर आ रही है या आपसे दूर जा रही है (या कभी-कभी दोनों)। आप एक इनपुट स्ट्रीम से सामान लेते हैं, आप एक आउटपुट स्ट्रीम पर सामान रखते हैं। कुछ कन्वेयर जो आप दीवार के एक छेद से बाहर आने के बारे में सोच सकते हैं - वे तलाशने योग्य नहीं हैं, पढ़ना या लिखना एक बार-केवल सौदा है। कुछ कन्वेयर आपके सामने रखे गए हैं, और आप उस स्ट्रीम में जहाँ आप पढ़ना / लिखना चाहते हैं, को चुनना चाहते हैं - जहाँ आप चाहते हैं।
जैसा कि IRBMe कहती है, हालांकि, यह उन कार्यों के संदर्भ में एक धारा के बारे में सोचना सबसे अच्छा है जो एक भौतिक सादृश्य के बजाय (जो कार्यान्वयन से कार्यान्वयन के लिए भिन्न होते हैं, लेकिन आम में बहुत कुछ है)। धाराएं "ऐसी चीजें हैं जिन्हें आप पढ़ या लिख सकते हैं"। जब आप स्ट्रीम एडेप्टर कनेक्ट करना शुरू करते हैं, तो आप उन्हें एक कन्वेयर के साथ एक बॉक्स के रूप में सोच सकते हैं, और एक कन्वेयर बाहर, कि आप अन्य धाराओं से कनेक्ट करते हैं और फिर बॉक्स डेटा पर कुछ परिवर्तन करता है (इसे ज़िप करना, या UNIXFfeeds बदलना) डॉस वाले, या जो भी हो)। पाइप्स रूपक का एक और संपूर्ण परीक्षण है: यह वह जगह है जहाँ आप धाराओं की एक जोड़ी बनाते हैं जैसे कि आप जो कुछ भी एक में लिखते हैं उसे दूसरे से बाहर पढ़ा जा सकता है। वर्महोल सोचें :-)
एक धारा पहले से ही एक रूपक है, एक सादृश्य है, इसलिए वास्तव में एक दूसरे को प्यार करने की कोई आवश्यकता नहीं है। आप इसे मूल रूप से पानी के प्रवाह के साथ एक पाइप के रूप में सोच सकते हैं जहां पानी वास्तव में डेटा है और पाइप धारा है। मुझे लगता है कि अगर धारा द्वि-दिशात्मक है तो यह एक तरह से 2-तरह का पाइप है। यह मूल रूप से एक सामान्य अमूर्तता है जो उन चीजों पर रखा जाता है जहां एक या दोनों दिशाओं में डेटा का प्रवाह या अनुक्रम होता है।
C #, VB.Net, C ++, Java आदि भाषाओं में, स्ट्रीम रूपक का उपयोग कई चीजों के लिए किया जाता है। फ़ाइल स्ट्रीम हैं, जिसमें आप एक फ़ाइल खोलते हैं और स्ट्रीम से पढ़ सकते हैं या इसे लगातार लिख सकते हैं; वहाँ नेटवर्क धाराएँ हैं जहाँ से धारा को पढ़ना और लिखना एक अंतर्निहित स्थापित नेटवर्क कनेक्शन से पढ़ना और लिखना है। इस उदाहरण में केवल लिखने के लिए धाराएँ आमतौर पर आउटपुट स्ट्रीम कहलाती हैं , और इसी तरह, जो धाराएँ केवल पढ़ने के लिए होती हैं, उन्हें इनपुट स्ट्रीम कहा जाता है, जैसे कि इस उदाहरण में।
एक स्ट्रीम डेटा का ट्रांसफ़ॉर्मेशन या एन्कोडिंग कर सकती है ( उदाहरण के लिए .slStream इन .net, SSL बातचीत डेटा को खा जाएगी और इसे आपसे छिपा देगी; टेलनेटस्ट्रीम टेलनेट वार्ताओं को आपसे छिपा सकता है, लेकिन डेटा तक पहुँच प्रदान कर सकता है; Java में ZipOutputStream आपको ज़िप फ़ाइल प्रारूप के आंतरिक के बारे में चिंता किए बिना एक ज़िप संग्रह में फ़ाइलों को लिखने की अनुमति देता है।
एक और आम बात जो आपको मिल सकती है वह है पाठ्य धाराएँ जो आपको बाइट्स के बजाय स्ट्रिंग्स लिखने की अनुमति देती हैं, या कुछ भाषाएं बाइनरी स्ट्रीम प्रदान करती हैं जो आपको आदिम प्रकार लिखने की अनुमति देती हैं। एक सामान्य बात जो आप पाठ्य धाराओं में पाएंगे, वह एक चरित्र एन्कोडिंग है, जिसके बारे में आपको जानकारी होनी चाहिए।
कुछ धाराएँ इस उदाहरण में यादृच्छिक अभिगम का समर्थन करती हैं । दूसरी ओर, एक नेटवर्क स्ट्रीम, स्पष्ट कारणों के लिए, नहीं।
UNIX जैसे ऑपरेटिंग सिस्टम भी प्रोग्राम इनपुट और आउटपुट के साथ स्ट्रीम मॉडल का समर्थन करते हैं, जैसा कि यहां वर्णित है ।
अब तक दिए गए जवाब बेहतरीन हैं। मैं केवल यह बताने के लिए एक अन्य प्रदान कर रहा हूं कि एक धारा बाइट्स का अनुक्रम नहीं है या प्रोग्रामिंग भाषा के लिए विशिष्ट नहीं है क्योंकि अवधारणा सार्वभौमिक है (जबकि इसका कार्यान्वयन अद्वितीय हो सकता है)। मैं अक्सर एसक्यूएल, या सी या जावा के संदर्भ में ऑनलाइन स्पष्टीकरण की एक बहुतायत देखता हूं, जो स्मृति स्थानों और निम्न स्तर के संचालन के साथ एक फिलस्ट्रीम सौदों के रूप में समझ में आता है। लेकिन वे अक्सर एक स्ट्रीम की अवधारणा पर चर्चा करने के बजाय एक फिलस्ट्रीम बनाने और अपनी दी गई भाषा में संभावित फ़ाइल पर संचालित करने के तरीके को संबोधित करते हैं।
जैसा कि उल्लेख किया गया है stream
कि एक रूपक है, कुछ अधिक जटिल का एक अमूर्त। अपनी कल्पना को काम करने के लिए मैं कुछ अन्य रूपकों की पेशकश करता हूं:
नली धारा है
नली, नोजल और संबंधित तंत्र गैस को आपके टैंक में प्रवाहित करने की अनुमति देते हैं
फ्रीवे स्ट्रीम है
तुम्हारे कान और आंखें धाराएं हैं
उम्मीद है कि आप इन उदाहरणों में देखेंगे कि धारा रूपक केवल इसके माध्यम से यात्रा करने के लिए (या फ्रीवे के मामले में) कुछ करने की अनुमति देने के लिए मौजूद हैं और खुद को हमेशा उस चीज को नहीं बनाते हैं जो वे स्थानांतरित कर रहे हैं। एक महत्वपूर्ण अंतर। हम अपने कानों को शब्दों के अनुक्रम के रूप में संदर्भित नहीं करते हैं। एक नली अभी भी एक नली है यदि इसके माध्यम से कोई पानी नहीं बह रहा है, लेकिन हमें इसे एक स्पिगोट से जोड़ना होगा, क्योंकि यह अपना काम सही ढंग से करता है। एक कार केवल 'तरह का' वाहन नहीं है जो एक फ्रीवे को पार कर सकता है।
इस प्रकार एक स्ट्रीम मौजूद हो सकती है जिसमें कोई डेटा नहीं है जो तब तक यात्रा करता है जब तक वह किसी फ़ाइल से जुड़ा हुआ है ।
अगला, हमें कुछ सवालों के जवाब देने की आवश्यकता है। मैं स्ट्रीम का वर्णन करने के लिए फ़ाइलों का उपयोग करने जा रहा हूँ ... एक फ़ाइल क्या है? और हम एक फ़ाइल कैसे पढ़ते हैं? मैं अनावश्यक जटिलता से बचने के लिए अमूर्तता के एक निश्चित स्तर को बनाए रखते हुए इसका उत्तर देने का प्रयास करूंगा और इसकी सादगी और पहुंच के कारण एक लिनक्स ऑपरेटिंग सिस्टम के सापेक्ष फ़ाइल की अवधारणा का उपयोग करूंगा।
एक फ़ाइल एक अमूर्त है :)
या, जैसा कि मैं समझा सकता हूं, एक फ़ाइल फाइल का वर्णन करने वाला एक हिस्सा डेटा संरचना है और एक हिस्सा डेटा जो वास्तविक सामग्री है।
डेटा संरचना भाग (UNIX / linux सिस्टम में एक इनोड कहा जाता है) सामग्री के बारे में जानकारी के महत्वपूर्ण टुकड़ों की पहचान करता है, लेकिन इसमें स्वयं सामग्री (या उस मामले के लिए फ़ाइल का नाम) शामिल नहीं है। जानकारी के टुकड़ों में से एक यह एक मेमोरी एड्रेस है जहां सामग्री शुरू होती है। तो एक फ़ाइल नाम (या लिनक्स में एक कड़ी) के साथ, एक फाइल डिस्क्रिप्टर (एक संख्यात्मक फ़ाइल नाम जिसे ऑपरेटिंग सिस्टम परवाह करता है) और स्मृति में एक शुरुआती स्थान हमारे पास कुछ है जिसे हम एक फ़ाइल कह सकते हैं।
(कुंजी टेकवे एक 'फाइल' है जिसे ऑपरेटिंग सिस्टम द्वारा परिभाषित किया गया है क्योंकि यह ओएस है जिसे अंततः इससे निपटना है। और हां, फाइलें बहुत अधिक जटिल हैं)।
अब तक सब ठीक है। लेकिन हम फ़ाइल की सामग्री को कैसे प्राप्त करते हैं, अपने प्रेमी को एक प्रेम पत्र कहते हैं, इसलिए हम इसे प्रिंट कर सकते हैं?
यदि हम परिणाम से शुरू करते हैं और पीछे की ओर बढ़ते हैं, जब हम अपने कंप्यूटर पर एक फ़ाइल खोलते हैं तो इसकी पूरी सामग्री हमें पढ़ने के लिए हमारी स्क्रीन पर छप जाती है। पर कैसे? बहुत विधिपूर्वक उत्तर है। फ़ाइल की सामग्री स्वयं एक अन्य डेटा संरचना है। वर्णों की एक सरणी मान लीजिए। हम इसे एक स्ट्रिंग के रूप में भी सोच सकते हैं।
तो हम इस स्ट्रिंग को कैसे पढ़ते हैं? स्मृति में अपने स्थान को खोजने और हमारे चरित्र के सरणी के माध्यम से पुनरावृत्ति करते हुए, फ़ाइल चरित्र के अंत तक पहुंचने तक एक समय में एक चरित्र। दूसरे शब्दों में एक कार्यक्रम।
जब इसका प्रोग्राम कहा जाता है तो एक स्ट्रीम 'क्रिएट' हो जाती है और इसमें संलग्न या कनेक्ट होने के लिए मेमोरी लोकेशन होता है । हमारे पानी की नली उदाहरण की तरह, नली एक अप्रभावी है अगर यह एक स्पिगोट से जुड़ा नहीं है। धारा के मामले में, इसे अस्तित्व में लाने के लिए इसे एक फाइल से जोड़ा जाना चाहिए।
धाराओं को और अधिक परिष्कृत किया जा सकता है, उदाहरण के लिए, इनपुट प्राप्त करने के लिए एक धारा या मानक आउटपुट में एक फाइल सामग्री भेजने के लिए एक धारा। UNIX / linux हमारे लिए बैट, स्टडिन (मानक इनपुट), स्टडआउट (मानक आउटपुट) और स्टैडर (मानक त्रुटि) को बंद करने के लिए 3 फाइलस्ट्रीम को जोड़ता है और खुला रखता है। धाराओं को डेटा संरचनाओं के रूप में स्वयं या ऑब्जेक्ट के रूप में बनाया जा सकता है जो हमें उनके माध्यम से डेटा स्ट्रीमिंग के अधिक जटिल संचालन करने की अनुमति देता है, जैसे स्ट्रीम को खोलना, स्ट्रीम को बंद करना या फ़ाइल की स्ट्रीम की जांच करने में त्रुटि से जुड़ा हुआ है। C ++ cin
का एक स्ट्रीम ऑब्जेक्ट का एक उदाहरण है।
निश्चित रूप से, यदि आप ऐसा चुनते हैं, तो आप अपनी स्ट्रीम लिख सकते हैं।
एक धारा कोड का एक पुन: प्रयोज्य टुकड़ा है जो डेटा पर प्रदर्शन करने के लिए उपयोगी संचालन प्रदान करते समय डेटा से निपटने की जटिलता को सार करता है।
एक और सादृश्य: आप एक स्ट्रीम के खिलाफ तैर नहीं सकते, इसीलिए आप स्ट्रीम से अगला बिट, बाइट, स्ट्रिंग या ऑब्जेक्ट ले सकते हैं, जबकि पहले से पढ़ा हुआ डेटा डिलीट हो जाता है। एक तरह से टिकट ... या मूल रूप से दृढ़ता का भंडारण किए बिना सिर्फ एक कतार ।
तो क्या हमें कतारों की आवश्यकता है? आप तय करें।
"स्ट्रीम" शब्द चुना गया है क्योंकि यह (वास्तविक जीवन में) एक बहुत ही समान अर्थ है जो हम इसका उपयोग करते समय व्यक्त करना चाहते हैं।
सादृश्य के बारे में एक जल धारा के बारे में सोचना शुरू करें। आपको डेटा का एक सतत प्रवाह प्राप्त होता है, जैसे नदी में लगातार पानी बहता रहता है। आप जरूरी नहीं जानते कि डेटा कहां से आ रहा है, और सबसे अधिक बार आपको इसकी आवश्यकता नहीं है; यह एक फ़ाइल, एक सॉकेट, या किसी अन्य स्रोत से हो, यह वास्तव में मायने नहीं रखता (नहीं) होना चाहिए। यह पानी की एक धारा प्राप्त करने के समान है, जिससे आपको यह जानने की आवश्यकता नहीं है कि यह कहाँ से आ रहा है; यह एक झील, एक फव्वारा, या किसी अन्य स्रोत से हो, यह वास्तव में मायने नहीं रखता (नहीं) होना चाहिए। स्रोत