2010-08-24 3 views
7

के साथ कुशलतापूर्वक विशाल फ़ाइलों को कैसे विलय करना है मेरे पास ~ 100 एमबी की 125 से अधिक टीएसवी फाइलें हैं जिन्हें मैं विलय करना चाहता हूं। मर्ज ऑपरेशन को 125 फाइलों को नष्ट करने की अनुमति है, लेकिन डेटा नहीं। क्या बात यह है कि अंत में, मैं सभी फ़ाइलों की सामग्री की एक बड़ी फ़ाइल के साथ एक दूसरे के बाद समाप्त होता हूं (कोई विशिष्ट आदेश नहीं)।सी #

क्या ऐसा करने का कोई प्रभावी तरीका है? मैं सोच रहा था कि क्या विंडोज़ उन सभी फ़ाइलों का एक बड़ा "संघ" बनाने के लिए एक एपीआई प्रदान करता है? अन्यथा, मुझे सभी फाइलें पढ़नी होंगी और एक बड़ा लिखना होगा।

धन्यवाद!

+0

पुनश्च: यहाँ एक नजर है (संभव डुप्लिकेट): http://stackoverflow.com/questions/444309/what-would-be-the-fastest-way- टू-कॉन्सटेनेट-तीन-फाइल-इन-सी – Abel

उत्तर

17

तो "विलय" वास्तव में सिर्फ फाइलों को एक दूसरे के बाद लिख रहा है? यह बहुत सरल है - बस एक आउटपुट स्ट्रीम खोलें, और फिर बार-बार इनपुट स्ट्रीम खोलें, डेटा कॉपी करें, बंद करें। उदाहरण के लिए:

static void ConcatenateFiles(string outputFile, params string[] inputFiles) 
{ 
    using (Stream output = File.OpenWrite(outputFile)) 
    { 
     foreach (string inputFile in inputFiles) 
     { 
      using (Stream input = File.OpenRead(inputFile)) 
      { 
       input.CopyTo(output); 
      } 
     } 
    } 
} 

Stream.CopyTo विधि है जो नेट 4 में नया है उपयोग कर रहा है यही कारण है कि आप नेट 4 उपयोग नहीं कर रहे हैं, तो एक और सहायक विधि काम में आएगा:

private static void CopyStream(Stream input, Stream output) 
{ 
    byte[] buffer = new byte[8192]; 
    int bytesRead; 
    while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0) 
    { 
     output.Write(buffer, 0, bytesRead); 
    } 
} 

वहाँ कुछ भी नहीं है कि मुझे पता है कि इससे अधिक कुशल है ... लेकिन महत्वपूर्ण बात यह है कि यह आपके सिस्टम पर बहुत अधिक स्मृति नहीं लेगा। ऐसा नहीं है कि यह बार-बार पूरी फाइल को स्मृति में पढ़ रहा है और फिर इसे फिर से लिख रहा है।

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

+0

मुझे लगता है कि प्रश्न का आपका उत्तर नहीं है? –

+0

@Marcus: मुझे ऐसा लगता है ... हालांकि मुझे यकीन नहीं था कि ओपी ऊपर स्ट्रीम स्ट्रीम संस्करणों को सहज महसूस कर रहा होगा। –

+0

मदद के लिए जॉन धन्यवाद! :) मुझे "CopyTo" के बारे में पता नहीं था। – Martin

0

आप ऐसा क्यों करना चाहते हैं?

कम स्तर के विखंडन के साथ एक तरीका हो सकता है, अगर आप इसे काम करने के लिए शांत हो जाएंगे तो अच्छा होगा।

यहां सी # के लिए एक रैपर है।

http://blogs.msdn.com/b/jeffrey_wall/archive/2004/09/13/229137.aspx

2

कमांड लाइन से कार्य करें:

copy 1.txt+2.txt+3.txt combined.txt 

या

copy *.txt combined.txt 
+1

आपको एहसास है कि उसने कहा ** 125 ** फाइलें, है ना? यह टाइप करने के लिए बहुत लंबा और कठिन हो जाएगा। यदि आपने कॉपी स्ट्रिंग जेनरेट करने के लिए सी # प्रोग्राम दिया है, तो यह एक * आंशिक * उत्तर हो सकता है। – Aaronaught

+6

दोस्त, फिर फ़ाइल मास्क के साथ दूसरा विकल्प का उपयोग करें। या एक डीआईआर कमांड करें (यानी, डीआईआर/बी केवल फाइलनाम प्राप्त करने के लिए), फ़ाइल में फ़ाइल नामों को कैप्चर करें, और एक अच्छे टेक्स्ट एडिटर में कमांड का निर्माण करें। 125 फ़ाइल नाम टाइप करने से बचने के लिए _many_ तरीके हैं। –

+0

मुद्दा यह है कि, आप सवाल का जवाब देने के करीब भी नहीं आए थे। आपने समस्या डोमेन के बारे में अनुमानों का एक टन बनाया है जिसे आप संभवतः नहीं जानते हैं। डोमेन के बारे में अधिक जानकारी के लिए * पूछना * ठीक है लेकिन यह मानने के लिए कि प्रश्न लेखक ने अपनी समस्या का समाधान करने का गलत तरीका चुना है। -1 आपके संभावित अप्रासंगिक समाधान और आपके तर्कवादी स्वर के लिए, "दोस्त"। – Aaronaught

2

आप मर्ज साथ मतलब है कि आप कुछ कस्टम तर्क क्या लाइनों जाना के साथ तय करना चाहते हैं कहा पे? या क्या आपका मतलब है कि आप मुख्य रूप से फ़ाइलों को एक बड़े में जोड़ना चाहते हैं?

बाद के मामले में, यह संभव है कि आप इस प्रोग्राम के रूप में करने के लिए (, हटाने अगर जरूरत नहीं /b द्विआधारी के लिए है) की जरूरत नहीं है सब पर, बस इस के साथ एक बैच फ़ाइल उत्पन्न:

copy /b "file 1.tsv" + "file 2.tsv" "destination file.tsv" 

सी # का उपयोग करके, मैं निम्नलिखित दृष्टिकोण लेगा। एक साधारण समारोह लिखें कि प्रतियां दो धाराओं:

void CopyStreamToStream(Stream dest, Stream src) 
{ 
    int bytesRead; 

    // experiment with the best buffer size, often 65536 is very performant 
    byte[] buffer = new byte[GOOD_BUFFER_SIZE]; 

    // copy everything 
    while((bytesRead = src.Read(buffer, 0, buffer.Length)) > 0) 
    { 
     dest.Write(buffer, 0, bytesRead); 
    } 
} 

// then use as follows (do in a loop, don't forget to use using-blocks) 
CopStreamtoStream(yourOutputStream, yourInputStream); 
+0

@ हारूनॉट: जब मैंने सबमिट किया, तो मैं आधा रास्ते था, फिर मैंने दूसरा भाग लिखा। लेकिन, दूसरे पैरा में थोड़ा संकेत दें: * "बस एक बैच फ़ाइल जेनरेट करें" *। उत्पन्न करके, मेरा मतलब है: स्वचालित रूप से बनाएं। लेकिन फिर मैंने सी # कोड जोड़ने का फैसला किया :) – Abel