2012-11-05 9 views
5

यह स्पर्शरेखीय an earlier question of mine.नियमित अभिव्यक्ति का उपयोग कर फ़ाइल में पढ़ें?

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

दुर्भाग्यवश, सामान्य पठन लाइन भी स्वीकार्य नहीं है, क्योंकि डेटा की कुछ पंक्तियों में मैं पढ़ रहा हूं जिसमें स्टैक निशान शामिल हैं - वे स्पष्ट रूप से /r/n का उपयोग अपने प्रारूपण में करते हैं। आदर्श रूप से, मैं कार्यक्रम को आगे पढ़ने के लिए बताना चाहता हूं जब तक कि यह एक रेगेक्स के लिए एक मैच हिट नहीं करता है, जो उसके बाद आता है। .NET में ऐसा करने के लिए कोई कार्यक्षमता है? यदि नहीं, तो क्या मुझे कुछ सुझाव मिल सकते हैं कि मैं इसे लिखने के बारे में कैसे जाऊं?

संपादित करें: यह थोड़ा आसान मेरे सवाल का पालन करने के लिए करने के लिए यहां अनुकूलित कोड के महत्वपूर्ण भागों में से कुछ की एक पेस्ट है:

foreach (var fileString in logpath.Select(log => new StreamReader(log)).Select(fileStream => fileStream.ReadToEnd())) 
{ 
    const string junkPattern = @"\[(?<junk>[0-9]*)\] \((?<userid>.{0,32})\)"; 
    const string severityPattern = @"INFO|ERROR|FATAL"; 
    const string datePattern = "^(?=[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2},[0-9]{3})"; 
    var records = Regex.Split(fileString, datePattern, RegexOptions.Multiline); 
    foreach (var record in records.Where(x => string.IsNullOrEmpty(x) == false)) 
    ...... 

समस्या Foreach में निहित है। .Select(fileStream => fileStream.ReadToEnd()) मेमोरी बुरी तरह से उड़ाएगा, मुझे बस पता है।

+4

और वहां आपके मुख्य कारणों में से एक है जो मुझे वास्तव में इस तरह के कार्यों के लिए RegEx का उपयोग करने की परवाह नहीं है। यदि आपने एक साधारण पार्सर लिखा है, तो आप इसे नई लाइनों को संभालने के लिए अनुकूलित कर सकते हैं। –

+0

@ जोनाथनवुड पूरे रिकॉर्ड के बाद व्यक्तिगत रिकॉर्ड को पार करने के लिए रेगेक्स अद्भुत हैं। मैं बस अपनी सारी जानकारी को पॉप आउट करता हूं और यह सीधे संबंधित क्षेत्रों में जाता है। समस्या इस मामले में फ़ाइल इनपुट है, ऐसा लगता है कि यह मुझे फ़ाइल के साथ एक समय में एक रिकॉर्ड देने के लिए पर्याप्त लचीला नहीं है। लेकिन यह फर्जी लगता है, है ना? यह एक असामान्य समस्या नहीं हो सकती है। – tmesser

+1

तो एक स्टैक ट्रेस/आर/एन है। वह रीडलाइन को क्यों खत्म करता है? – Paparazzi

उत्तर

1

सबसे पहले, आपको कक्षा की घोषणा में अपनी कॉन्स परिभाषा को स्थानांतरित करना चाहिए - संकलक आपके लिए ऐसा करेगा, लेकिन यह बेहतर कोड पठनीयता के लिए ही किया जाना चाहिए।

@Blam उल्लेख किया है, आप इस तरह StringBuilder और जोड़ी में StreamReader.ReadLine, कुछ का उपयोग करना चाहिए:

foreach(var filePath in logpath) 
{ 
    var sbRecord = new StringBuilder(); 
    using(var reader = new StreamReader(filePath)) 
    { 
     do 
     { 
      var line = reader.ReadLine(); 
      // check start of the new record lines 
      if (Regex.Match(line, datePattern) && sbRecord.Length > 0) 
      { 
       // your method for log record 
       HandleRecord(sbRecord.ToString()); 
       sbRecord.Clear(); 
       sbRecord.AppendLine(line); 
      } 
      // if no lines were added or datePattern didn't hit 
      // append info about current record 
      else 
      { 
       sbRecord.AppendLine(line); 
      } 
     } while (!reader.EndOfStream) 
    } 
} 

मैं अपनी समस्या के बारे में कुछ समझ में नहीं आया, तो टिप्पणी में यह स्पष्ट करें।
इसके अलावा, आप अपने आवेदन की गति के लिए, अपनी लाइनों के कार्यों को शेड्यूल करने के लिए ThreadPool का उपयोग कर सकते हैं।

+0

मैंने अपने स्वयं के समाधान को कोडिंग समाप्त कर दिया जो निम्न स्तर के आधार पर धारा से संबंधित है, क्योंकि मुझे लगा कि यह बिल्कुल बेतुका था कि मैं एक मानक स्ट्रीम टोकन को पाठ स्ट्रीम नहीं कर सका। हालांकि, मूल रूप से किसी और के लिए यह आपको कम या ज्यादा करना है। – tmesser

+0

@YYY मई आप रिकॉर्ड के लिए यहां अपना कोड प्रदान कर सकते हैं? मुझे लगता है कि यह दिलचस्प होगा। – VMAtm

+0

जितना मुझे यह करना अच्छा लगेगा, यह जल्द ही कुछ बैंकिंग सॉफ्टवेयर का हिस्सा बनने जा रहा है और इसलिए स्वामित्व है। उस ने कहा, जब मुझे काम से कुछ दिन मिलते हैं तो मेरे एजेंडे पर चीजों में से एक ओपन सोर्स वर्जन बनाना और इसे अपने जीथब में जोड़ना है, इसलिए मैं समाधान का विस्तार कर सकता हूं। चूंकि यह अभी खड़ा है, मैं मूल रूप से बाइट्स की एक निश्चित संख्या में पढ़ता हूं और एक फ़ाइल स्थिति रखता हूं, जो हमारे प्रोजेक्ट के संदर्भ में बहुत अच्छा काम करता है लेकिन यह एक अच्छा सामान्यीकृत समाधान नहीं है। एक बार जब मैं अपने प्रारंभिक काम को डुप्लिकेट/sanitize और इसे github में जोड़ता हूं तो वह महत्वाकांक्षा जारी रहेगी। – tmesser

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