दिलचस्प पोस्ट
जावा का उपयोग कर सेलेनियम वेबड्राइवर में नई विंडो को कैसे संभाल पाएं? प्रोटोटाइप का उद्देश्य क्या है? PHP में बहु-आयामी सरणी से डुप्लिकेट मान कैसे निकालें मैं एक वैश्विक, म्यूट्यूबल सिंगलटन कैसे बनाऊं? प्रॉक्सी के पीछे से एसबीटी का उपयोग कैसे करें? @ आईडी / एंड्रॉइड: सूची और @ + आईडी / सूची के बीच क्या अंतर है डाटासैट को बदलते बिना डेटाग्रिड दृश्य फ़िल्टर करना नए भौतिक विषय में वापस तीर का रंग कैसे बदल सकता है? data.table बनाम dplyr: क्या एक अच्छी तरह से कुछ कर सकता है जो अन्य नहीं कर सकता है या खराब नहीं कर सकता है? Magento – एक विशिष्ट विशेषता मान के साथ उत्पादों को पुनर्प्राप्त करें क्या है? = ऑपरेटर का मतलब है? डिफ़ॉल्ट निर्माता बनाम इनलाइन फ़ील्ड इनिशियलाइज़ेशन विशिष्ट बटन क्लिक होने पर सत्यापन को कैसे छोड़ें? अपवाद पर सी ++ प्रदर्शित स्टैक ट्रेस कैसे मेरी कक्षा के लिए एक स्वैप समारोह प्रदान करने के लिए?

फ़ाइल। प्रतिलिपि बनाम मैनुअल फाइलस्ट्रीम। फ़ाइल को कॉपी करने के लिए लिखें

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

public void Copy(System.IO.Stream inStream, string outputFilePath) { int bufferSize = 1024 * 64; using (FileStream fileStream = new FileStream(outputFilePath, FileMode.OpenOrCreate, FileAccess.Write)) { int bytesRead = -1; byte[] bytes = new byte[bufferSize]; while ((bytesRead = inStream.Read(bytes, 0, bufferSize)) > 0) { fileStream.Write(bytes, 0, bytesRead); fileStream.Flush(); } } } 

क्या किसी को पता है कि यह फ़ाइल की तुलना में इतनी धीमी प्रदर्शन करता है.कॉपी? क्या प्रदर्शन में सुधार करने के लिए मैं कुछ भी कर सकता हूं? क्या मुझे यह देखने के लिए कि मैं एक खिड़की से दूसरे स्थान पर नकल कर रहा हूं, विशेष लॉजिक डाल रहा हूं – इस स्थिति में मैं सिर्फ फाइल का उपयोग करूँगा। कॉपी और अन्य मामलों में मैं धाराओं का उपयोग करूँगा?

कृपया मुझे बताएं कि आप क्या सोचते हैं और आपको अतिरिक्त जानकारी की आवश्यकता है। मैंने अलग बफर आकारों की कोशिश की है और ऐसा लगता है कि हमारे "छोटी" फाइलों के लिए एक 64k बफर आकार इष्टतम है और हमारी "बड़ी" फ़ाइलों के लिए 256k + बेहतर बफर आकार है – लेकिन किसी भी मामले में यह फ़ाइल से बहुत खराब प्रदर्शन करता है। )। अग्रिम में धन्यवाद!

वेब के समाधान से एकत्रित समाधान "फ़ाइल। प्रतिलिपि बनाम मैनुअल फाइलस्ट्रीम। फ़ाइल को कॉपी करने के लिए लिखें"

File.Copy कॉपीफ़ाइल Win32 फ़ंक्शन के आसपास बनाया गया था और यह फ़ंक्शन एमएस चालक दल से बहुत ध्यान देता है (धीमी प्रति प्रदर्शन के बारे में यह विस्टा-संबंधित थ्रेड याद है)।

आपकी विधि के प्रदर्शन में सुधार करने के लिए कई सुराग:

  1. जैसा कि कई ने कहा है कि आपके चक्र से पहले फ्लश विधि को हटा दिया गया था। आपको इसे बिल्कुल भी ज़रूरत नहीं है।
  2. बढ़ती बफ़र मदद कर सकता है, लेकिन केवल फ़ाइल-टू-फ़ाइल कार्रवाई पर, नेटवर्क शेयरों के लिए, या FTP सर्वर इसके बजाय इसे धीमा कर देगा। 60 * 1024 नेटवर्क शेयरों के लिए आदर्श है, कम से कम विस्टा से पहले। अधिकांश मामलों में एफटीपी 32 के लिए पर्याप्त होगा
  3. अपनी कैशिंग रणनीति (आपके मामले में अनुक्रमिक पढ़ना और लिखने में) प्रदान करके, फाइलस्ट्रीम कन्स्ट्रक्टर ओवरराइड का उपयोग करें FileOptions पैरामीटर (SequentalScan) के साथ।
  4. आप एसिंक्रोनस पैटर्न (विशेषकर नेटवर्क-टू-फाईल के मामलों के लिए उपयोगी) का उपयोग करके प्रतिलिपि तेज कर सकते हैं, लेकिन इसके लिए थ्रेड्स का उपयोग न करें, इसके बजाय ओवरलैप IO (BeginRead, EndRead, BeginWrite, EndWrite .net) का उपयोग करें, और भूलें फ़ाइल स्ट्रिम कन्स्ट्रक्टर में एसिंक्रोनस विकल्प सेट करें (देखें FileOptions )

अतुल्यकालिक प्रति स्वरूप का उदाहरण:

 int Readed = 0; IAsyncResult ReadResult; IAsyncResult WriteResult; ReadResult = sourceStream.BeginRead(ActiveBuffer, 0, ActiveBuffer.Length, null, null); do { Readed = sourceStream.EndRead(ReadResult); WriteResult = destStream.BeginWrite(ActiveBuffer, 0, Readed, null, null); WriteBuffer = ActiveBuffer; if (Readed > 0) { ReadResult = sourceStream.BeginRead(BackBuffer, 0, BackBuffer.Length, null, null); BackBuffer = Interlocked.Exchange(ref ActiveBuffer, BackBuffer); } destStream.EndWrite(WriteResult); } while (Readed > 0); 

रिफ्लेक्टिंग को खत्म करना हम उस फ़ाइल को देख सकते हैं। कॉपी वास्तव में Win32 API को कॉल करता है:

 if (!Win32Native.CopyFile(fullPathInternal, dst, !overwrite)) 

जो करने के लिए हल करता है

 [DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true)] internal static extern bool CopyFile(string src, string dst, bool failIfExists); 

और यहाँ CopyFile के लिए दस्तावेज है

आप ऑपरेटिंग सिस्टम को अपने खुद के कोड के साथ इतना कुछ करने में कभी भी हरा नहीं पाएंगे, भले ही आपने इसे कोडांतरक में सावधानीपूर्वक तैयार नहीं किया।

यदि आपको यह सुनिश्चित करने की ज़रूरत है कि आपका कार्य सर्वोत्तम प्रदर्शन के साथ होता है और आप विभिन्न स्रोतों को मिलाकर मिलान करना चाहते हैं तो आपको संसाधन प्रकार का वर्णन करने वाला एक प्रकार बनाने की आवश्यकता होगी फिर आप उस एपीआई बनाते हैं, जैसे कि ऐसी Copy जैसी कार्य है जिसमें दो प्रकार के होते हैं और दोनों के विवरणों की जांच करने से श्रेष्ठ निष्पादित कॉपी तंत्र चुन लिया जाता है। उदाहरण के लिए, यह निर्धारित करने के बाद कि दोनों स्थानों में विंडोज़ फ़ाइल स्थान हैं, जो आप फ़ाइल को चुनते हैं। प्रतिलिपि या यदि स्रोत खिड़की की फाइल है लेकिन गंतव्य HTTP पोस्ट होना है तो यह वेबआरव्यूस्ट का उपयोग करता है

तीन बदलाव नाटकीय रूप से प्रदर्शन में सुधार करेंगे:

  1. अपना बफ़र आकार बढ़ाएं, 1 एमबी (अच्छी तरह से प्रयोग करें) का प्रयास करें
  2. आपके फ़ाइल स्ट्रीम को खोलने के बाद, डिस्कस्टो फ्रंट पर पूरे ब्लॉक को आवंटित करने के लिए fileStream.SetLength (inStream.Length) को कॉल करें (केवल काम करता है यदि इनस्ट्रीम तलाश करने योग्य है)
  3. FileStream.Flush () निकालें – यह बेमानी है और संभवतः प्रदर्शन पर एक सबसे बड़ा प्रभाव पड़ता है क्योंकि जब तक फ्लश पूरा नहीं हो जाता तब तक इसे ब्लॉक किया जाएगा। धारा को निपटाने के लिए वैसे भी फ्लश किया जाएगा।

मैंने प्रयोग किए गए प्रयोगों में लगभग 3-4 गुना तेज लग रहा था:

  public static void Copy(System.IO.Stream inStream, string outputFilePath) { int bufferSize = 1024 * 1024; using (FileStream fileStream = new FileStream(outputFilePath, FileMode.OpenOrCreate, FileAccess.Write)) { fileStream.SetLength(inStream.Length); int bytesRead = -1; byte[] bytes = new byte[bufferSize]; while ((bytesRead = inStream.Read(bytes, 0, bufferSize)) > 0) { fileStream.Write(bytes, 0, bytesRead); } } } 

एक बात जो बाहर खड़ा है वह है कि आप एक हिस्सा पढ़ रहे हैं, वह हिस्सा लिखते हुए, एक और खंड पढ़ना और इसी तरह।

स्ट्रीमिंग ऑपरेशन मल्टीथ्रेडिंग के लिए महान उम्मीदवार हैं। मेरा अनुमान है कि फ़ाइल। कॉपी मल्टीथ्रेडिंग लागू करता है

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

फ्लश कॉल को निकालने का प्रयास करें, और उसे लूप के बाहर ले जाने का प्रयास करें।

आईओ को फ्लश करने के लिए कभी-कभी ओएस सबसे अच्छा जानता है .. इससे इसकी आंतरिक बफ़र्स का उपयोग बेहतर होता है

यहां एक समान उत्तर है

मैं एक स्ट्रीम की सामग्री को दूसरे में कैसे कॉपी करूँ?

आपकी मुख्य समस्या फ्लश () को कॉल है, जो आपके प्रदर्शन को I / O की गति से बाँध देगा

मार्क रसेलोविच इस पर अधिकार होगा।

उन्होंने अपने ब्लॉग पर एक प्रविष्टि Inside Vista SP1 फ़ाइल प्रतिलिपि सुधार लिखा था जो विस्टा SP1 के माध्यम से कला के विंडोज राज्य को बताता है।

मेरा अर्ध-शिक्षित अनुमान है कि फाइल होगा.कॉपी स्थितियों की सबसे बड़ी संख्या से अधिक मजबूत होगी। बेशक, इसका मतलब कुछ विशिष्ट कोने के मामले में नहीं है, आपका अपना कोड इसे हरा सकता है …