2009-08-17 9 views
5

मैंने विंडोज़ एप्लिकेशन बनाया है जो लोड बैलेंस सर्वर से नियमित डाउनलोड फ़ाइल है, वर्तमान में गति लगभग 30 एमबी/सेकेंड है। हालांकि मैं फास्टकोपी या टेराकोपी का उपयोग करने की कोशिश करता हूं, यह लगभग 100 एमबी/सेकेंड पर प्रतिलिपि बना सकता है। मैं जानना चाहता हूं कि मेरी प्रतिलिपि की गति को कैसे सुधारें ताकि यह वर्तमान में फ़ाइल की तुलना में तेज़ी से कॉपी कर सके।मेरी एप्लिकेशन कॉपी फ़ाइल को तेज़ी से कैसे बनाएं

उत्तर

4

धाराओं का उपयोग करते समय एक आम गलती एक समय में एक बाइट की प्रतिलिपि बनाना, या एक छोटे बफर का उपयोग करना है। डिस्क पर डेटा लिखने में ज्यादातर समय लगता है कि एक बड़ा बफर का उपयोग करके आपके औसत खोज समय प्रति बाइट कम हो जाएगा।

ऑपरेटिंग सिस्टम क्लस्टर में डिस्क पर फ़ाइलों को लिखते हैं। इसका मतलब यह है कि जब आप डिस्क पर एक बाइट लिखते हैं तो विंडोज वास्तव में 512 बाइट्स और 64 केबी के बीच एक ब्लॉक लिख देगा। आप एक बफर का उपयोग कर बेहतर डिस्क प्रदर्शन प्राप्त कर सकते हैं जो 64kb का एक पूर्णांक एकाधिक है।

इसके अतिरिक्त, आप एक बफर का उपयोग करने से बढ़ावा प्राप्त कर सकते हैं जो आपके CPUs के अंतर्निहित स्मृति पृष्ठ आकार का एक बहु है। X86/x64 मशीनों के लिए इसे 4kb या 4mb पर सेट किया जा सकता है।

तो आप 4 एमबी के पूर्णांक एकाधिक का उपयोग करना चाहते हैं।

इसके अतिरिक्त यदि आप एसिंक्रोनस आईओ का उपयोग करते हैं तो आप बड़े बफर आकार का पूरी तरह से लाभ उठा सकते हैं।

class Downloader 
{ 
    const int size = 4096 * 1024; 
    ManualResetEvent done = new ManualResetEvent(false); 
    Socket socket; 
    Stream stream; 

    void InternalWrite(IAsyncResult ar) 
    { 
     var read = socket.EndReceive(ar); 
     if (read == size) 
      InternalRead(); 
     stream.Write((byte[])ar.AsyncState, 0, read); 
     if (read != size) 
      done.Set(); 
    } 

    void InternalRead() 
    { 
     var buffer = new byte[size]; 
     socket.BeginReceive(buffer, 0, size, System.Net.Sockets.SocketFlags.None, InternalWrite, buffer); 
    } 

    public bool Save(Socket socket, Stream stream) 
    { 
     this.socket = socket; 
     this.stream = stream; 

     InternalRead(); 
     return done.WaitOne(); 
    } 
} 

bool Save(System.Net.Sockets.Socket socket, string filename) 
{ 
    using (var stream = File.OpenWrite(filename)) 
    { 
     var downloader = new Downloader(); 
     return downloader.Save(socket, stream); 
    } 
} 
2

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

1

सबसे आसान तरीका कच्चे में फ़ाइल खोलने के लिए है हस्तांतरण की गति तक ही सीमित है/बाइनरी मोड (वह सी निश्चित नहीं है कि सी # समकक्ष है) और एक समय में बहुत बड़े ब्लॉक (कई एमबी) को पढ़ें और लिखें।

1

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

आपको अपनी स्थिति के लिए इष्टतम पाने के लिए ब्लॉक की संख्या और उन ब्लॉकों के आकार के साथ चारों ओर घूमना होगा। मैंने सी ++ का उपयोग करके इस विधि का उपयोग किया और हमारे लिए इष्टतम 256 केबी के चार ब्लॉक का उपयोग कर रहा था जब नेटवर्क शेयर से स्थानीय डिस्क पर कॉपी किया गया था।

सादर,

Sebastiaan

1

आप चलाते हैं Process Monitor आप ब्लॉक आकार कि Windows Explorer या TeraCopy उपयोग कर रहे हैं देख सकते हैं।

विस्टा में स्थानीय नेटवर्क के लिए डिफ़ॉल्ट ब्लॉक आकार 2 एमबी से अधिक है, जो फ़ाइलों को एक विशाल पाइप पर बहुत तेज़ी से कॉपी करता है।

0

पहिया को फिर से क्यों शुरू करें?

यदि आपकी स्थिति अनुमति देती है, तो आप शायद खुद को लिखने की कोशिश करने की तुलना में मौजूदा "तेज़" कॉपी उपयोगिताओं में से एक को खोलने से बेहतर हो सकते हैं। ऐसे कई गैर-स्पष्ट किनारे-मामले हैं जिन्हें संभालने की आवश्यकता है, और लगातार अच्छे perf प्राप्त करने के लिए बहुत सारे परीक्षण-अंत-त्रुटि प्रयोग की आवश्यकता होती है।

+0

क्या मैं स्क्रिप्टिंग (कमांड लाइन) के लिए "तेज़" कॉपी उपयोगिताओं का उपयोग कर सकता हूं ?? – Kiquenet

+0

कम से कम कुछ स्क्रिप्ट योग्य हैं - रोबोकॉपी एक उदाहरण है। – Addys

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