2013-10-24 64 views
5

我有一個項目作爲計劃任務運行,每5分鐘。除此之外,該項目通過數百個圖像運行,並以這種方式將它們複製到網絡驅動器中。File.Copy()性能如果文件可能已經存在

foreach (string file in Files) 
{ 
    string Control = Path.GetFileNameWithoutExtension(file); 
     File.SetAttributes(file, FileAttributes.Normal); 
     try 
     { 
      File.Copy(file, destinationFolder + "\\" + Control + @".pdf", false); 
     } 
     catch (Exception err) 
     { 
      Console.Writeline(err.ToString()); 
     } 
} 

「假」的說法當然告訴它不覆蓋文件,如果它已經存在。

這是比第一次檢查文件是否已經存在,然後只在文件不存在時才複製更快/更好的做法嗎? (見下)

foreach (string file in Files) 
{ 
    if (File.Exists(destinationFolder + "\\" + ControlNumber + ".pdf") == false) 
    { 
     File.SetAttributes(file, FileAttributes.Normal); 
     File.Copy(file, destinationFolder + "\\" + ControlNumber + @".pdf"); 
    } 
} 

我的直覺告訴我,第一個是更好的方法。不過,我對編程相對比較陌生,並且很想知道哪個更好,更快,更廣泛地被接受等等。

謝謝!

編輯: 它可能會或可能不會讓你知道,遠程驅動器/文件夾,我複製到包含圖像數據(百萬計的圖像)的4TB

+3

http://ericlippert.com/2012/12/17/performance-rant/ –

+0

如果將所有現有文件的路徑寫入文本或xml文件中,然後檢查是否更好首先列出,如果它不在該列表中,則複製到目錄中,然後將新文件添加到列表中?只是一個想法:) –

+0

你是如何創建'文件'集合? –

回答

5

測試了這個結果如下本地驅動器上:

1000次檢查文件是否存在,然後做一個File.Copy如果沒有:28.29毫秒

1000次做有覆蓋一個File.Copy設置爲false在try, catch317.13毫秒

測試結果如下網絡驅動器上:

1000次檢查文件是否存在,如果沒有則執行File.Copy203。48毫秒

1000次做與覆蓋集File.Copy,以虛假的try, catch14758.74毫秒

基於這一點,我會覺得很明顯,首先進行文件檢查會更有效。

+0

非常有趣,與反直覺接壤。在使用我的2個選項秒錶後,我看到非常相似的結果。 – Milne

+0

在我的測試中,應該注意它正在嘗試相同的文件,所以它每次都存在。 –

+0

我認爲需要在這裏添加的是,try/catch塊需要大量的CPU來處理......它可能會減慢速度,但沒關係。第二種方式好多了。 – Yuki

0

無論是那些很可能是最快的方法來解決這個問題。我要做的是在遠程驅動器上撥打Directory.GetFiles,比較結果,只複製所需的文件。

這樣,只有一個網絡ls-equivalent操作,並且只有您需要的複製操作。

+1

遠程驅動器是4TB大的數百萬個圖像文件。聽起來有點低效。 – Milne

+1

@ColtonMilne你應該看看'rsync'及其算法。 –

+0

@ ta.speot.is感謝+1,rsync非常有趣,雖然比我想要的簡單應用稍微複雜一些。 – Milne

2

你更可能看到使用第一種情況下更好的性能(雖然確保您纏繞呼叫File.Copytry..catch,因爲它會拋出一個IOException如果文件不存在,你的第一個例子讓底層平臺處理文件存在的檢查,它可以優化你的代碼不能的方式,由於每次通話的網絡往返時間,大大減少呼叫次數將會有性能增益

另外,遠程系統可能會在您撥打File.ExistsFile.Copy的電話之間發生變化,而後者可能會覆蓋您在檢查和啓動時間之間創建的文件複製。

更好的方法是先在遠程機器上創建一個文件列表,然後只複製那些不存在的文件。當你做這個副本時,用你的第一個方法try..catch。這可以確保您不會浪費時間試圖複製啓動時存在的文件,並且確保您在開始複製事項後不會意外覆蓋創建的文件。

+0

我看到你說有數百萬個文件,但它們可能並不都在一個目錄中。如果您將文件移動到的目錄數量與文件數量相比較大(可能類似於1:5,但您必須進行配置以找到正確的數字),那麼您只需使用第一種技術。如果目錄數量很少,並且要複製的文件數量很大,那麼您關心的每個目錄中的所有文件名稱的單次傳輸相對於您必須進行的往返次數嘗試複製每個文件。 – seawolf

相關問題