2016-02-10 14 views
8

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

क्या कोई तरीका है जब मैं फ़ाइल से हैंडल स्ट्रीम से उपलब्ध नहीं है? मैं StreamReader से फ़ाइल हैंडल खो जाने पर एक फ़ाइल नोट नहीं होने की उम्मीद कर रहा था।

यहाँ मेरी कोड स्निपेट है ...

 string file = @"Z://1601120903.csv"; //Network file 
     string line; 
     StringBuilder stb = new StringBuilder();  
     StreamReader stream = new StreamReader(file, Encoding.UTF8, true, 1048576); 
     do 
     { 
      line = stream.ReadLine(); 
      // Do some work here 
     } while (line != ""); 
+3

स्ट्रीम रीडर हैंडल "खो" नहीं सकता है। यदि यह वास्तव में कैश किए गए डेटा का उपयोग नहीं कर सकता है और फ़ाइल सामग्री प्राप्त करने के लिए नेटवर्क को हिट करना है तो अंतर्निहित ReadFile() कॉल विफल हो जाएगी और आपको सिस्टम प्राप्त होगा। IEException। कौन सी रिपोर्ट "नेटवर्क त्रुटि", फाइलों को पढ़ने के दौरान गलत हो सकती है कि कई चीजों में से एक। आप अपवाद पकड़ लेंगे और उपयोगकर्ता को इसके बारे में बताएंगे ताकि वह समस्या को ठीक करने के लिए जो भी आवश्यक हो, वह कर सके। –

+1

मैं इस पर विचार कर रहा हूं कि इसे बंद करना है या नहीं, क्योंकि यहां एक बग है जो इस कोड में दिखाई नहीं दे रहा है। यहां दिखाया गया कोड वास्तविक कोड का सरलीकृत संस्करण होना चाहिए। – usr

+0

@ हंसपैसेंट, हाँ मैंने शुरुआत में भी यही बात सोचा था। लेकिन अगर आप कोड की इस पंक्ति को निष्पादित करते हैं, तो आप इस मुद्दे का अनुभव करेंगे। यह अपवाद नहीं फेंकता क्योंकि यह मुझे एक ही पंक्ति को अनिश्चित काल तक फेंकता रहता है। – Asanka

उत्तर

7
+0

मैंने उन दो गुणों की जांच की। नेटवर्क समस्याओं के कारण फ़ाइलहेडल गिरा दिए जाने के बाद, ये दोनों शर्तें सत्य और स्ट्रीम लौट जाएंगी। रीडलाइन() एक ही पंक्ति को बार-बार वैरिएबल लाइन पर आउटपुट करती है। – Asanka

+0

@Asanka मैंने वास्तविक उत्तर परीक्षण के कुछ परिणामों के साथ अपने उत्तरों को अद्यतन किया है। – DmitryG

+0

अजीब। यह मुझे कोई अपवाद नहीं फेंक दिया। जब आप फाइल रीड ऑपरेशन के बीच में होते हैं तो क्या आप कनेक्शन छोड़ देते हैं? – Asanka

17

साथ null नहीं साथ रिक्त स्ट्रिंग की तुलना करें:

https://msdn.microsoft.com/en-us/library/system.io.streamreader.readline(v=vs.110).aspx

वापसी मूल्य प्रकार: से अगली पंक्ति System.String इनपुट स्ट्रीम, या शून्य स्ट्रीम इनपुट अंत का अंत तक पहुंच गया है।

do 
    { 
     line = stream.ReadLine(); 
     // Do some work here 
    } while (line != null); 

एक बेहतर दृष्टिकोण, हालांकि, नेट आप के लिए काम करते (लाइन फ़ाइल पढ़ने से लाइन) करते हैं और सभी पाठकों ड्रॉप करने के लिए है:

foreach (String line in File.ReadLines(file)) { 
    // Do some work here 
    } 
+1

क्या यह 'string.IsNullOrEmpty (line)' जैसे कुछ का उपयोग करने के लिए कोड को बेहतर करेगा? – terbubbs

+4

@terbubbs: नहीं, एक * खाली स्ट्रिंग * फ़ाइल –

+0

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

0

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

आप जगह आप तक पहुँच के सूचकांक इस मदद कर सकता है प्राप्त करना चाहते हैं:

while ((line = sr.ReadLine()) != null) 
{ 
    Console.WriteLine(line); 
} 

Source

+0

स्थानीय रूप से फ़ाइल की प्रतिलिपि बनाना एक अच्छा समाधान जैसा लगता है। लेकिन एक संभावना हो सकती है कि फ़ाइल स्वयं काफी बड़ी है – Asanka

+1

यह उस समस्या का समाधान नहीं करता है जो उसके पास है। वह गलत तरीके से मानता है कि एक ही पंक्ति बार-बार उत्पादन हो सकती है। इसके बजाय, यह उसके कोड के साथ एक बग है। – usr

+0

@Asanka जैसा कि मैंने कहा है कि फ़ाइल की प्रतिलिपि बनाना संभव है या नहीं, और यदि आप अभी भी वर्तमान पाठक अनुक्रमणिका का ट्रैक रखना चाहते हैं तो आपको जो समाधान जोड़ा है उसका उपयोग करना चाहिए। –

3

आप एक while -loop के साथ लिखते हैं (EndOfStream):

using(StreamReader sr = new StreamReader(...)) { 
    while(!sr.EndOfStream) { 
     string line = sr.ReadLine(); 
     Console.WriteLine(line); 
    } 
} 

सही दृष्टिकोण 2 (Peek)

using(StreamReader sr = new StreamReader(...)) { 
    while(sr.Peek() >= 0) { 
     string line = sr.ReadLine(); 
    } 
} 

नोट: यह है कि यह फ़ाइल के अंत के रूप में एक खाली स्ट्रिंग खतरा सही नहीं है।

यदि नेटवर्क कनेक्शन कुछ बिंदु पर खो दिया है, जबकि मैं पढ़ रहा हूँ, यह बार-बार एक अनंत पाश में पाशन stream.ReadLine से परिणाम के रूप में एक ही पंक्ति जिसके परिणामस्वरूप द्वारा (एक ही पंक्ति में रहेंगे)

मैंने अभी इस परिदृश्य की जांच की है - System.IO.IOException ("नेटवर्क पथ नहीं मिला।"} इस मामले में फेंक दिया जाना चाहिए।

कोशिश करने वाले ब्लॉक के साथ इसे लपेटना मेरी समस्या को ठीक नहीं करेगा, है ना?

इस मामले में आप पढ़ने के रूप में इस तोड़ सकते हैं:

string line; 
do { 
    try { 
     line = sr.ReadLine(); 
     // Do some work here 
    } 
    catch(System.IO.IOException) { 
     break; 
    } 
} while(line != null); 
1

एक और तरीका File.ReadAllLines() का उपयोग किया जाएगा और यह फ़ाइल खोलने और सभी लाइनों और closig पढ़ने का ख्याल रखेंगे फ़ाइल और नेटवर्क कनेक्शन खो जाने पर परिदृश्य को भी संभाल सकता है।

var lines = File.ReadAllLines("Z://1601120903.csv"); 

foreach(line in lines) 
{ 
// Do some work 
} 
संबंधित मुद्दे