2012-08-06 3 views
7

मैं एक FileStream के साधन (यह एक बहुत बड़ी फाइल है और मैं बस पूरी बात को फिर से लिखने के बिना शीर्ष लेख को बदलने की जरूरत से एक फ़ाइल में फेरबदल कर रहा हूँ।मैं कैसे पता लगा सकता हूं कि फ़ाइल में यूनिक्स लाइन फ़ीड्स ( n) या Windows लाइन फ़ीड्स ( r n) है या नहीं?

फ़ाइल या तो यूनिक्स या Windows लाइन फ़ीड, और यह हो सकता है मेरे लिए यह जानना महत्वपूर्ण है कि जब मैं इसे अद्यतन करता हूं तो मैं सही लाइन फीड वर्णों को फ़ाइल में वापस लिख सकता हूं।

मैं ब्लॉक में फ़ाइल को पढ़ने के लिए फ़ाइलस्ट्रीम का उपयोग करने के लिए एक सरल कार्य लिख सकता हूं और जांच कर सकता हूं लाइन फीड अक्षर

लेकिन यह समस्या पहले से हल होनी चाहिए, अगर सी # में नहीं तो Win32 API में?

फ़ाइल की लाइन फ़ीड शैली का पता लगाने का सबसे प्रभावी तरीका क्या है?

+0

सुनिश्चित नहीं है, इसलिए टिप्पणी, लेकिन नियमित अभिव्यक्ति का उपयोग करना संभव होगा जैसे: \ r \ n $ '? यह जांच करेगा कि लाइन फीड '\ r \ n' के साथ समाप्त होती है। यदि ऐसा नहीं होता है, तो, यह एक यूनिक्स लाइन होना चाहिए। – npinti

+0

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

+0

क्या आप गारंटी दे सकते हैं कि सभी लाइन समाप्ति फाइल के भीतर सुसंगत हैं? तकनीकी रूप से एक ही फ़ाइल में अलग-अलग मिश्रित रेखा समाप्ति होना संभव होगा। –

उत्तर

2

आपके सुझावों के लिए धन्यवाद। मैं आश्चर्यचकित था कि कुछ आसानी से पुन: प्रयोज्य नहीं ढूंढ पाया, इसलिए मैंने एक सरल कार्य बनाया जिसमें मैं यहां शामिल हूं।ध्यान दें कि यह केवल पहला न्यूलाइन वर्ण (\ n या \ r \ n) पाता है और इसे मैच के रूप में देता है। मेरी जरूरतों के लिए पर्याप्त है, लेकिन शायद मजबूत नहीं है।

public bool TryDetectNewLine(string path, out string newLine) 
    { 
     using (var fileStream = File.OpenRead(path)) 
     { 
      char prevChar = '\0'; 

      // Read the first 4000 characters to try and find a newline 
      for (int i = 0; i < 4000; i++) 
      { 
       int b; 
       if ((b = fileStream.ReadByte()) == -1) break; 

       char curChar = (char)b; 

       if (curChar == '\n') 
       { 
        newLine = prevChar == '\r' ? "\r\n" : "\n"; 
        return true; 
       } 

       prevChar = curChar; 
      } 

      // Returning false means could not determine linefeed convention 
      newLine = Environment.NewLine; 
      return false; 
     } 
    } 
2

दुर्भाग्यवश मुझे नहीं लगता कि यह यूनिक्स या डॉस फ़ाइल होने पर 100% निश्चित होने का एक तरीका है क्योंकि अधिकांश संपादक खोले/सहेजे जाने पर 'गलत' समाप्ति वाली फ़ाइल को सही नहीं करते हैं।

मैं और "\ r \ n" घटनाओं के लिए खोज और एक साधारण सांख्यिकीय विश्लेषण का उपयोग करते हुए एक धारा के रूप में फ़ाइल को पढ़ने हैं केवल '\ n'

(यानी जो एक उच्चतम हिट संख्या अधिक है) पर खोज का नतीजा आपको सही जवाब देगा। अगर फ़ाइल बड़ी है, तो फ़ाइल का पहला एक्स% पढ़ना पर्याप्त होगा।

एक सरल समाधान केवल "\ r \ n" के लिए खोजना है और यदि पाया जाता है, तो मान लें कि यह एक डॉस फ़ाइल है। फ़ाइल मशीन से उत्पन्न होने पर यह 100% तक काम करना चाहिए।

.NET Framework/WinAPI में किसी मौजूदा कोड के लिए, मुझे अभी तक कोई भी ऐसा ऑपरेशन नहीं करना है जो इस ऑपरेशन को निष्पादित करता है।

3

जैसा कि प्रति कहा गया है कि पाठ फ़ाइल की सामग्री को बिना खोलने और बाइट्स के माध्यम से स्ट्रीमिंग के बिना वास्तव में कोई रास्ता नहीं है। यदि आप फ़ाइल डाउनलोड करने के लिए http का उपयोग करते हैं, तो आप लापरवाही कर सकते हैं, आप एक माइम प्रकार प्राप्त कर सकते हैं जो फ़ाइल के प्रकार को निष्क्रिय करता है, लेकिन अक्सर इसकी "ऑक्टेट-स्ट्रीम" होती है।

जबकि आप इसे मजबूर कर सकते हैं, और जब तक आप एक लाइन फीड ("\ n") नहीं पाते हैं तब तक पढ़ लें, फिर एक चरित्र का बैक अप लें और देखें कि कैरिज रिटर्न ("\ r") है, तो मैं एक और अधिक सांख्यिकीय दृष्टिकोण क्योंकि आपको डेटा को किसी भी तरह से पढ़ना है।

1) पढ़ने के लिए बाइट्स का एक नमूना आकार चुनें जिसमें आपको फ़ाइल से कम से कम 2 या 3 रिकॉर्ड्स प्राप्त करना चाहिए।

2) एक हिस्टोग्राम के रूप में प्रत्येक बाइट मुठभेड़ (i'assassign एकल बाइट चार सेट सेट) स्टोर करें। आप बाइट वैल्यू द्वारा अनुक्रमित एक आरी में अपनी गिनती संग्रह करके ऐसा कर सकते हैं या आप एक शब्दकोश का उपयोग कर सकते हैं।

3) कैरिज रिटर्न और लाइन फीड मानों की गणना करें। यदि आपके पास लाइन फीड गिनती है और कोई कैरिज रिटर्न नहीं है, तो यह एक यूनिक्स फ़ाइल है। यदि कैरिज रिटर्न और लाइन फीड गिना जाता है तो यह एक विंडोज फाइल है।

यह दृष्टिकोण आपको इनबाउंड फ़ाइल पर गुणवत्ता जांच के लिए करने की अनुमति देगा। क्या आपके पास हिस्टोग्राम में charcaters है जो अंपा संख्यात्मक नहीं हैं? फिर किसी ने आपको एक बाइनरी फाइल पास कर दी है। सभी ऊपरी मामले की उम्मीद है? फिर उपरोक्त वर्णों के बाहर की गणना कीजिए। एक गैर पाठ फ़ाइल को संसाधित करने के लिए आप कई चेक कर सकते हैं।

+1

आपके और @ पेर्स समाधान दोनों मानते हैं कि सभी लाइन समाप्ति प्रति फ़ाइल के अनुरूप हैं। जंगली में, यह मिश्रित लाइन समाप्त करने वाले मार्करों के लिए तकनीकी रूप से बहुत संभव हो सकता है। –

+2

सच है, लेकिन यहां व्यायाम करना है अगर कोई व्यायाम करना है फ़ाइल यूनिक्स या विंडोज़ है। मुझे लगता है कि इनबाउंड फाइलें एक प्रारूप में हैं या दूसरी सवाल के बारे में बताई गई है। अगर किसी ने मिश्रित एलएफ और सीआर/एलएफ को रिकॉर्ड समाप्त कर दिया है, तो शायद यह कोई फर्क नहीं पड़ता कि हेडर पंक्ति समाप्त हो गई थी। – user957902

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