2010-02-15 7 views
6

큰 파일을 처리하기 전에 프로그래밍 방식으로 다운로드해야합니다. 그렇게하는 가장 좋은 방법은 무엇입니까? 파일이 크므로 강제로 종료 할 수 있도록 특정 시간을 기다려야합니다.C에서 큰 파일을 프로그래밍 방식으로 다운로드하는 방법

WebClient.DownloadFile()에 대해 알고 있습니다. 그러나 강제로 나가기 위해 기다릴 시간을 특정하는 방법이 보이지 않습니다.

try 
{ 
    WebClient client = new WebClient(); 
    Uri uri = new Uri(inputFileUrl); 
    client.DownloadFile(uri, outputFile); 
} 
catch (Exception ex) 
{ 
    throw; 
} 

또 다른 방법은 ProcessStartInfo를 사용 프로세스 'WaitForExit을 사용하여 명령을 파일을 다운로드 발사 명령 줄 유틸리티 (wget을)를 사용하는 것입니다 강제로 종료하려면 (밀리 INT).

ProcessStartInfo startInfo = new ProcessStartInfo(); 
//set startInfo object 

try 
{ 
    using (Process exeProcess = Process.Start(startInfo)) 
    { 
     //wait for time specified 
     exeProcess.WaitForExit(1000 * 60 * 60);//wait till 1m 

     //check if process has exited 
     if (!exeProcess.HasExited) 
     { 
      //kill process and throw ex 
      exeProcess.Kill(); 
      throw new ApplicationException("Downloading timed out"); 
     } 
    } 
} 
catch (Exception ex) 
{ 
    throw; 
} 

더 좋은 방법이 있습니까? 도와주세요. 감사.

+0

이 URI 기능이 도움이 진행 비율을

e.ProgressPercentage 

희망을 알 수있는 다음과 같은 웹 클라이언트의 이벤트와 다음 시도 @BFree 말했듯이 DownloadFileAsync을 사용할 수 있습니다 ? 그것은 ftp입니까? – t0mm13b

답변

16

WebRequest을 사용하고 response stream을 얻습니다. 그런 다음 응답 블록의 바이트 블록에서 읽은 다음 각 블록을 대상 파일에 씁니다. 이 방법 당신은 다운로드가 너무 오래 걸리는 경우 덩어리 사이의 제어를 얻을 수로, 중단시기를 제어 할 수 있고 다운로드가 시계에 따라 시간이 초과 된 경우를 결정할 수 있습니다 :            

 DateTime startTime = DateTime.UtcNow; 
     WebRequest request = WebRequest.Create("http://www.example.com/largefile"); 
     WebResponse response = request.GetResponse(); 
     using (Stream responseStream = response.GetResponseStream()) { 
      using (Stream fileStream = File.OpenWrite(@"c:\temp\largefile")) { 
       byte[] buffer = new byte[4096]; 
       int bytesRead = responseStream.Read(buffer, 0, 4096); 
       while (bytesRead > 0) {  
        fileStream.Write(buffer, 0, bytesRead); 
        DateTime nowTime = DateTime.UtcNow; 
        if ((nowTime - startTime).TotalMinutes > 5) { 
         throw new ApplicationException(
          "Download timed out"); 
        } 
        bytesRead = responseStream.Read(buffer, 0, 4096); 
       } 
      } 
     } 
+0

@ rip, 어떻게 복잡합니까? – juan

+0

@Juan, 동기식입니다. 이 예제의 비동기 버전은 매우 다르게 보일 것입니다. 또한 시간의 90 %를 차지하는 스트림 관리 기능을 숨기는 매우 사용자 친화적 인 WebClient 외관을 제공합니다. – Josh

+1

orip을 사용하면 코드가 훨씬 간단 해집니다. Remus의 코드를 사용하는 한 가지 이점은 파일의 얼마나 많은 부분을 다운로드 할 수 있는지입니다. – hIpPy

7

방법 WebClient 클래스에서 DownloadFileAsync을 사용하는 방법에 대해 설명합니다. 이 길로가는 멋진 점은 너무 오래 걸리면 CancelAsync을 호출하여 작업을 취소 할 수 있다는 것입니다. 기본적으로이 메서드를 호출하고 지정된 시간이 경과하면 취소를 호출합니다.

4

여기 질문 : C#: Downloading a URL with timeout

간단한 솔루션 :

public string GetRequest(Uri uri, int timeoutMilliseconds) 
{ 
    var request = System.Net.WebRequest.Create(uri); 
    request.Timeout = timeoutMilliseconds; 
    using (var response = request.GetResponse()) 
    using (var stream = response.GetResponseStream()) 
    using (var reader = new System.IO.StreamReader(stream)) 
    { 
     return reader.ReadToEnd(); 
    } 
} 

더 나은 (유연) 솔루션은 WebClientWithTimeout 헬퍼 클래스의 형태로, 같은 질문에 this answer입니다.

+4

webrequest.timeout은 응답 본문을 다운로드 할 때까지의 총 시간이 아니라 HTTP 응답 헤더가 수신 될 때까지의 시간 만 측정합니다. 예. GetResponse가 리턴 할 때까지의 시간에 영향을줍니다. –

+0

좋은 점, 나는 그 사실을 몰랐다. – orip

2

당신은

protected virtual void OnDownloadProgressChanged(DownloadProgressChangedEventArgs e); 
protected virtual void OnDownloadFileCompleted(AsyncCompletedEventArgs e); 

는 그런 다음

관련 문제