2009-10-19 6 views
6

में फ़ाइलों के बहुत सारे प्रतिलिपि बनाई जा रही अपने आवेदन में मैं 1000 छोटे फ़ाइलोंडेल्फी

यहाँ है मैं कोड का उपयोग कर रहा कॉपी करना होगा, लेकिन यह बहुत धीमा वहाँ ऐसा करने का एक बेहतर तरीका है है?

procedure Tdatafeeds.RestotreTodaysFiles; 
var 
    SearchRec: TSearchRec; 
    FromFn, ToFn: string; 
Begin 
    if DirectoryExists(BackupPath1) then 
    begin 
     try 
     if FindFirst(BackupPath1 + '\*.*', (faAnyFile AND NOT(faDirectory)), SearchRec) = 0 then 
     begin 
      repeat 
      FromFn := BackupPath1 + '\' + SearchRec.name; 
      ToFn := DatafeedsPath1 + '\' + SearchRec.name; 
      CopyFile(Pchar(FromFn), Pchar(ToFn), false); 
      until FindNext(SearchRec) <> 0; 
     end; 
     finally 
     FindClose(SearchRec); 
     end; 
    end; 
End; 
+1

कई छोटी फ़ाइलों की प्रतिलिपि आई/ओ मुद्दों को प्रभावित कर सकती है, खासकर धीमी डिस्क के साथ। डिस्क हेड को फ़ाइलों को देखने और उन्हें कॉपी करने के लिए खाली स्थान खोजने के लिए बहुत कुछ स्थानांतरित करना पड़ता है। यदि आप कमांड लाइन से उन फ़ाइलों की प्रतिलिपि बनाते हैं, तो क्या सिस्टम बहुत तेज है? –

उत्तर

10

निश्चित रूप से SHFileOperation() साथ जाना, CopyFile रास्ता भी है कि कई फ़ाइलों के लिए धीमी है । ऐसा लगता है कि आप मूल रूप से एक संपूर्ण फ़ोल्डर को पुनर्स्थापित कर रहे हैं, इसलिए खोज फ़ंक्शन अनावश्यक और धीमी चीजें आगे हो सकती है। कुछ इस तरह मदद की हो सकती है:

uses ShellApi; 

function CopyDir(const fromDir, toDir: string): Boolean; 
var 
    fos: TSHFileOpStruct; 
begin 
    ZeroMemory(@fos, SizeOf(fos)); 
    with fos do 
    begin 
    wFunc := FO_COPY; 
    fFlags := FOF_FILESONLY; 
    pFrom := PChar(fromDir + #0); 
    pTo := PChar(toDir) 
    end; 
    Result := (0 = ShFileOperation(fos)); 
end; 

इस समारोह मौजूदा फ़ाइलों को अधिलेखित करने के लिए संकेत बढ़ा देंगे, हालांकि (शायद यह है कि छोड़ फेरबदल किया जा सकता है), लेकिन उपयोगकर्ता का चयन कर सकते "सभी" तो यह एक एक क्लिक के बाद प्रक्रिया, बहुत तेज, एक प्रगति पट्टी है और वांछित अगर रद्द किया जा सकता है।

+1

किसी भी संकेत से बचने के लिए ** FOF_NOCONFIRMATION ** और ** FOF_NOCONFIRMMKDIR ** झंडे देखें। संदर्भ: http://msdn.microsoft.com/en-us/library/bb759795%28VS.85%29.aspx – stukelly

+5

क्या CopyFile से SHFileOperation() तेज बनाता है? –

0

शायद आप (XCOPY) की तरह एक ही बार में डिस्क के लिए स्मृति में फाइलों का एक समूह को पढ़ने और फिर लिख उन सब के साथ प्रयोग कर सकते हैं। यह फाइल सिस्टम पर अच्छा हो सकता है।

7

आप SHFileOperation() एपीआई कॉल का उपयोग कर सकते हैं और संरचना के फ़ाइल नाम में वाइल्डकार्ड का उपयोग कर सकते हैं। इस तरह एक कॉल का उपयोग सभी फ़ाइलों को एक ही बार में कॉपी करने के लिए किया जाएगा। प्रगति दिखाने के लिए भी संभावना है (कॉलबैक फ़ंक्शन के माध्यम से) और उपयोगकर्ता को ऑपरेशन रद्द करने की अनुमति दें।

+0

CopyFileEx() कॉलबैक को भी अनुमति देगा, और मुझे आश्चर्य होगा कि SHFileOperation CopyFileEx() को भी कॉल करना समाप्त नहीं करेगा। –

+1

सच है, लेकिन एमएसडीएन दस्तावेज 'CopyFileEx()' से AFAICS स्रोत के लिए वाइल्डकार्ड की अनुमति नहीं देगा। इसलिए 'SHFileOperation() '(या Vista और उससे आगे' IFileOperation' इंटरफ़ेस 'का उपयोग करके फ़ाइल ढूंढने के लूप को भी प्रतिस्थापित किया जाएगा। – mghie

+0

धन्यवाद - SHFileOperation() अच्छी तरह से काम करता है प्रतिलिपि अब सेकंड लेता है - इसमें कुछ मिनट लगने से पहले :) –

2

मैं अभी अपने कोड का परीक्षण नहीं कर सकता है, लेकिन बाहर की जाँच इस को सही संस्करण के रूप में ऊपर सुझाव

// (!) faAnyFile-faDirectory <--- this is wrong 
    // we don't subtract flag values because the value will be meaningless 
    if FindFirst(BackupPath1 + '\*.*', faAnyFile, SearchRec) = 0 then 
    begin 
     repeat 
     if not (SearchRec.Attr and faDirectory) 
      And SearchRec.Name <> "." 
      And SearchRec.Name <> ".." Then 
     Begin 
      FromFn := BackupPath1 + '\' + SearchRec.name; 
      ToFn := DatafeedsPath1 + '\' + SearchRec.name; 
      CopyFile(Pchar(FromFn), Pchar(ToFn), false); 
     End; 
     until FindNext(SearchRec) <> 0; 
     FindClose(SearchRec); 
    end;