2013-10-24 3 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()); 
     } 
} 

"거짓"인수는 물론 파일이 이미 존재하는 경우 덮어 쓰지 않도록 지시합니다.

파일이 이미 있는지 먼저 확인한 다음 파일이없는 경우에만 복사하는 것보다 빠르고 더 나은 방법입니까? (아래 참조)

내 직감은 첫 번째 방법이 더 좋은 방법이라고 말해줍니다. 그러나 나는 프로그래밍에 비교적 익숙하지 않으며 어떤 것이 더 빠르고, 더 광범위하게 받아 들여지는지를 알고 싶어한다.

고마워!

편집 : 그것은 수도 있고 내가에 복사하고 원격 드라이브/폴더에 이미지 데이터 (이미지의 수백만)의 4TB 포함되어 있음을 알고 도움이 될 수 없습니다

+3

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

+0

기존 파일의 경로를 모두 텍스트 또는 XML 파일에 쓰고 그 파일을 검사하는 것이 더 좋지 않을까요? 목록에없는 경우 먼저 목록을 만든 다음 디렉토리에 복사 한 다음 목록에 새 파일을 추가 하시겠습니까? 그냥 아이디어 :) –

+0

'Files' 컬렉션을 어떻게 만들었습니까? –

답변

5

는 다음과 같은 결과를 로컬 드라이브에이 테스트 : 덮어 쓰기와 File.Copy을하고

1000 배를 28.29 밀리 초 : 파일이 다음 있지 않으면 File.Copy을하고,있는 경우 확인

1000 배 다음과 같은 결과를 네트워크 드라이브에서 테스트 317.13 밀리 초

:하십시오 try, catch false로 설정

파일이 존재하는지 1000 번 확인한 후 File.Copy 일 경우 : 203.try, catch false로 덮어 쓰기가 설정된 File.Copy을하고 48 밀리 초

1000 배 : 그 바탕으로 14758.74 밀리 초

, 내가 먼저 파일 검사를 수행하는 것이 더 효율적이 될 것이라고 분명 생각합니다.

+0

매우 직관적 인 측면에서 매우 흥미 롭습니다. 내 2 옵션 스톱워치를 사용한 후, 나는 매우 비슷한 결과를보고 있습니다. – Milne

+0

내 테스트에서, 그것은 동일한 파일을 시도하고 있었음을 주목해야한다. 그래서 매번 존재했다. –

+0

내가 여기에 추가해야 할 필요가있는 것은 try/catch 블록이 많은 CPU를 처리하는 것입니다 ... 속도가 느려지는 것은 중요하지만 중요하지 않습니다. 두 번째 방법은 훨씬 낫다. – Yuki

0

그 중 어느 것도 가장 빠른 방법이 될 것입니다 문제에 접근한다. 내가하려는 것은 원격 드라이브에서 Directory.GetFiles 전화를 걸어 결과를 비교하고 필요한 파일 만 복사하는 것입니다.

그런 식으로 단 하나의 네트워크 ls - 동등한 작업과 필요한만큼의 복사 작업 만 있습니다.

+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

관련 문제