2009-08-17 4 views
5

로드 밸런스 서버에서 루틴을 다운로드하는 Windows 응용 프로그램을 만들었습니다. 현재 속도는 약 30MB/초입니다. 그러나 FastCopy 또는 약 100MB/초로 복사 할 수있는 TeraCopy를 사용하려고합니다. 복사 속도를 향상시켜 현재보다 빨리 파일을 복사 할 수있는 방법을 알고 싶습니다.내 응용 프로그램 복사 파일을 더 빠르게 만드는 방법

답변

4

스트림을 사용할 때 한 가지 공통적 인 실수는 한 번에 한 바이트 씩 복사하거나 작은 버퍼를 사용하는 것입니다. 디스크에 데이터를 쓰는 데 소요되는 대부분의 시간은 탐색에 소요되므로 더 큰 버퍼를 사용하면 바이트 당 평균 탐색 시간이 줄어 듭니다.

운영 체제는 파일을 디스크의 디스크에 씁니다. 즉, 디스크에 단일 바이트를 쓸 때 Windows는 실제로 512 바이트와 64KB 사이의 블록을 쓰게됩니다. 64KB의 정수배 인 버퍼를 사용하면 훨씬 더 나은 디스크 성능을 얻을 수 있습니다.

또한 메모리 페이지 크기의 기본 CPU의 배수 인 버퍼를 사용하여 부스트를 얻을 수 있습니다. x86/x64 시스템의 경우 4KB 또는 4MB로 설정할 수 있습니다.

그래서 4mb의 정수배를 사용하고 싶습니다.

또한 비동기 IO를 사용하면 큰 버퍼 크기를 충분히 활용할 수 있습니다.

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

가장 간단한 방법은 원시에서 파일을 열 수있는 콘텐츠를 전송 장치의 속도로 제한됩니다/진 모드 (thats C는 C#에 상응하는 것이 확실하지 않습니다)를 읽고 한 번에 매우 큰 블록 (수 MB)을 읽고 씁니다.

1

TeraCopy가 사용하는 속임수는 읽기 및 쓰기 비동기를 만드는 것입니다. 즉, 다른 블록을 읽는 동안 데이터 블록을 쓸 수 있습니다.

상황에 맞는 최적의 결과를 얻으려면 블록 수와 블록 크기를 피팅해야합니다. C++을 사용하여이 방법을 사용했고 네트워크 공유에서 로컬 디스크로 복사 할 때 256KB의 네 블록을 사용하는 것이 최적이었습니다.

감사합니다,

1

당신이 Windows 탐색기 나 테라 카피가 사용하는 블록 크기를 볼 수 있습니다 Process Monitor을 실행하면

Sebastiaan.

Vista에서는 로컬 네트워크의 기본 블록 크기가 약 2MB로 커다란 파이프를 통해 파일을 복사하는 속도가 훨씬 빠릅니다.

0

왜 바퀴를 재발 명합니까?

상황에 따라, 기존의 "빠른"복사 유틸리티 중 하나를 직접 작성하는 것보다 나을 수도 있습니다. 처리해야 할 수많은 명확하지 않은 엣지 케이스가 있으며 일관되게 좋은 성능을 얻으려면 많은 시행 착오적 실험이 필요합니다.

+0

스크립팅 (명령 줄)에 "빠른"복사 유틸리티를 사용할 수 있습니까 ?? – Kiquenet

+0

적어도 일부는 스크립팅 가능합니다. robocopy가 그 한 예입니다. – Addys

관련 문제