2009-11-12 7 views
5

मान लीजिए हम इस तरह एक कोड ब्लॉक:स्ट्रीम पढ़ें समस्या

//Assuming s is a stream: 
byte[] data = new byte[1000]; 
s.Read(data,0,data.Length); 

पढ़ विधि 1 से 1000 बाइट्स से कहीं भी पढ़ सकता है, धारा अपठित के संतुलन हो जाता है।

यह सी # पुस्तक कहता है।

मुझे समझ में नहीं आता है, क्यों Read विधि स्ट्रीम से कहीं भी पढ़ी जाएगी? यह सभी धाराओं को पढ़ नहीं रहा है?

और यह कहते हैं काम के आसपास इस तरह होना चाहिए:

//bytesRead will always end up at 1000, unless the stream is itself smaller in length: 
int bytesRead = 0; 
int chunkSize = 1; 
while(bytesRead < data.Length && chunkSize > 0) 
     bytesRead += chunkSize = s.Read(data,bytesRead,dataLength-bytesRead); 

ऊपर इस कोड के रूप में भी एक काम के आसपास पुस्तक द्वारा प्रदान की जाती है। मैं यह समझने की कोशिश कर रहा हूं कि रीड विधि अंत में पढ़ने शुरू हो रही है और बाइट सरणी में निर्दिष्ट सीमा में सभी बाइट्स लिखना शुरू कर रहा है या नहीं। वह का उपयोग s.Read(data,bytesRead,dataLength-bytesRead);

में प्रारंभ बिंदु के रूप में क्यों कर रहा है।

उत्तर

8

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

नतीजतन, जब बाइट सरणी में एक हिस्सा पढ़ते हैं, तो आप बाइट सरणी भर नहीं सकते हैं। लेकिन आप अगले खंड को जोड़ना चाहते हैं जहां बाइट सरणी की शुरुआत को ओवरराइट करने के बजाए आखिरी बार छोड़ा गया था। इसलिए बाइट पास करना बाइट सरणी में अगले खंड को रखने के लिए प्रारंभिक स्थान के रूप में पढ़ें।

0

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

2

पहला उदाहरण Read विधि में इनपुट पैरामीटर के रूप में 1000 के बाइट सरणी के घोषित आकार का उपयोग कर रहा है।

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

मुझे लगता है कि आप कहां भ्रमित हो रहे हैं यह है कि लेखक कृत्रिम रूप से 1000 बाइट अधिकतम उदाहरण को सीमित कर रहा है।स्ट्रीमिंग को शामिल करने वाले बहुत से प्रोटोकॉल आमतौर पर शुरुआत में एक बाइट या दो भेजते हैं, विशेष रूप से पूरी तरह से स्ट्रीम की लंबाई के उपभोक्ता को सूचित करते हैं, इसलिए यह सबसे अच्छा हिस्सा हो सकता है और धारा को संसाधित कर सकता है ताकि 1,000 की कोई घोषित सीमा आवश्यक न हो। आप आकार प्राप्त करते हैं, आप इसे उचित रूप से खंडित करते हैं (अंतिम खंड जो पूर्णांक आकार नहीं हो सकता है), और प्रत्येक खंड को संसाधित करते हैं।

+0

आपका मतलब है, सबसे पहले वे उस डेटा का आकार भेजते हैं जिसे वे भेजना चाहते हैं और फिर वे पूरे डेटा को पूरी तरह भेजने के बजाए भाग के रूप में भेजते हैं? – Tarik

+0

आमतौर पर हाँ। मान लें कि आपके पास डिस्क पर 40 एमबी फ़ाइल है जिसे आप ट्रांसफर करना चाहते हैं। मेमोरी में 40 एमबी लोड करने के बजाय इसे स्थानांतरित करने के बजाय - और इस प्रकार 40 एमबी मेमोरी को लंबे समय तक भीड़ में डाल दिया जाता है - आप बस पढ़ते हैं, पहले 1024 बाइट्स कहें, इसे स्थानांतरित करें, और 1024 बाइट भागों में जारी रखें। एक फ़ाइल ट्रांसफर प्रोटोकॉल "पहले पैकेट के पहले दो बाइट्स में एक अनगिनत int शामिल है जो पेलोड के आकार को इंगित करता है" ताकि आप जान सकें कि उस स्ट्रीम से पढ़ने को कब रोकना है। प्राप्त करने वाला अंत ऐसा ही कर सकता है - इसे 1024 बाइट्स या कुछ अन्य संसाधन अनुकूल बफर नंबर में घुमाएं। – cfeduke

1

मुझे समझ में नहीं आता है, विधि स्ट्रीम से कहीं भी पढ़ा जाएगा? यह सभी स्ट्रीम नहीं पढ़ रहा है?

पढ़ना आपको पढ़ने के लिए प्रारंभ और समाप्ति बिंदु निर्दिष्ट करने की अनुमति देता है। अधिक जानकारी के लिए itowlson का जवाब देखें।

क्या मैं समझने के लिए पढ़ें कि क्या विधि के अंत पढ़ सकते हैं और बाइट सरणी निर्दिष्ट श्रेणी में बाइट्स के सभी लिखने के लिए शुरुआत है कोशिश कर रहा हूँ

यदि यह एक प्रश्न था तो मुझे लगता है कि उत्तर नहीं है। रीड विधि निर्दिष्ट शुरुआत और अंत बिंदुओं पर स्ट्रीम से डेटा के साथ एक सरणी भरती है।

वह बाइट्स का उपयोग क्यों कर रहा है s.Read (डेटा, बाइट्स रीड, डेटा लम्बाई-बाइट्स रीड) में प्रारंभ बिंदु के रूप में पढ़ें;

वह बाइट्स का उपयोग कर रहा है "बाइट्स पढ़ने की मात्रा" का ट्रैक रखने के लिए पढ़ें। इससे उन्हें पता चलता है कि अगली रीड कॉल पर कहां पढ़ना शुरू करना है।

4

वाक्यांश "1 से 1000 बाइट्स से कहीं भी पढ़ सकता है" का अर्थ है "1 बाइट, या 2 बाइट्स, 1000 बाइट तक पढ़ सकता है"। यह लंबाई बाइट्स पढ़ने के लिए संदर्भित करता है, स्थान नहीं। पढ़ने की वर्तमान स्थिति पर स्थित होगा।

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