2010-07-06 5 views
5

인터넷에서 파일을 다운로드하고 싶습니다.이 작업이 단순해야한다고 생각합니다. 몇 가지 다른 접근 방법을 시도하면서 나는 각각 하나의 단점이 있음을 발견했습니다. 주요 문제는 다음과 같습니다이 파일 Indy를 사용하는 중에 연결이 시간 초과되지 않습니다.

  • 응용 프로그램이 인터넷 연결이 응답하지 않습니다/서버 손실 영원히 경우 정지 다운로드 될 때까지

    • 응용 프로그램이 정지.

    (세부 정보 :

    How to retrieve a file from Internet via HTTP?
    The connection does not timeout while downloading file from internet는)

    그래서, 마침내는 인디으로 "프로"라이브러리를 사용하는 나는 여러 사람들로부터받은 제안을 사용했다. 그러나 Indy는 내가 시도한 코드 조각보다 훨씬 뛰어나다. (하지만 유지 보수가 훨씬 더 어렵고 어렵다.) Indy를 사용하는 동안 응용 프로그램은 짧은 기간 동안 만 멈추지 않으므로 여전히 (어쨌든) 사용할 수 있습니다. 그러나 다운로드가 완료 될 때까지 응용 프로그램을 종료 할 수 없습니다 (절대로 인터넷 연결이 끊어진 경우). http://borland.newsgroups.archived.at/public.delphi.internet.winsock/200609/0609079112.html 그래서
    https://forums.embarcadero.com/thread.jspa?threadID=25199&tstart=90

    , 나는 그것을 작동하게하기 위해 TIDAntiFreeze하기 위해해야 ​​할 일을했을 해킹 몇 가지가있다 :

    다른 사람들은 같은 문제를보고?

    또한 ConnectTimeout 속성이 인식되지 않습니다.

    fIDHTTP := TIDHTTP.Create(NIL); 
    fIDHTTP.ConnectTimeout:=5000; 
    

    나는 인디 삭제하고 별도의 스레드에서 파일을 다운로드하는 원래의 아이디어로 복귀하고 (나는 제 3의 라이브러리를 제거 적어도 이런 식으로) 응답하지 않을 때 스레드를 종료해야 하는가? 내가 이렇게하면 예기치 않은 부작용이있을 것입니까?

    델파이 7, 인디 10.1.5 10.5 (아마도).

    감사합니다.

  • +2

    스레드를 사용하여 백그라운드에서 파일을 다운로드하려고 시도 했습니까? – mjn

    +2

    인디 10.1.5는 매우 오래된, 현재 10.5.7입니다 – mjn

    +0

    새로운 버전의 인디는 내 컴퓨터에 설치를 거부합니다. – Ampere

    답변

    1

    이런 종류의 문제를 해결하는 것은 그리 어렵지 않습니다. 먼저해야 할 일은 오류 처리를 올바르게 처리했는지 확인하는 것입니다. 무언가가 실패하면 모든 것이 제대로 정리되는지 확인하십시오. 그 이상으로 다운로드 코드가 별도의 스레드의 일부인지 확인하십시오. 문제가있는 경우 항상 주 프로그램의 스레드를 종료 할 수 있습니다. 다음은 저를 위해 잘 작동하는 코드 (다운로드 전용, 쓰레드가 아님)입니다.

    with TDownloadURL.Create(nil) do 
        try 
        URL := 'myurltodownload.com'; 
        filename := 'locationtosaveto'; 
        try 
         ExecuteTarget(nil); 
        except 
         result := false; 
        end; 
        if not FileExists(filename) then 
         result := false; 
        finally 
        clear; 
        free; 
        end; 
    
    +0

    여기에서는이 토론의 요점을 다루지 않습니다. 인용구 : "응용 프로그램이 파일을 다운로드 할 때까지 정지됩니다." – Ampere

    +0

    내 글을 다시 읽고 Cosmin Prund의 답변을 참조하십시오. 우리 둘 다 당신이 쓰레드를 사용해야한다고 말하고 있습니다. 그렇지 않으면 이것을 막을 방법이 없습니다. Indy를 사용하더라도 스레드를 사용해야합니다. 주변에는 방법이 없습니다. 인디는 당신의 필요에 비해 너무 부피가 크다고 말했기 때문에 테스트 된 대안을 제공해야한다는 말과 함께 제공했습니다. 나는이 대답이 당신의 요점을 어떻게 다루지 않는지 보지 못합니다. 답변 : 쓰레기. – Daisetsu

    +0

    수락 된 답변입니다. – Ampere

    4

    아마도 Indy에게 Indy 방식으로 스레드를 사용해야합니다. Indy는 차단 모드에서 작동하도록 특별히 설계 되었기 때문에 대부분의 인터넷 프로토콜이 작동합니다 (예 : 프로토콜 수준에서 HTTP를 사용하여 요청을 보내면 응답을 읽습니다. 동시에 보내지도 않고 수신하지 못합니다). TIdAntiFreeze는 스레드를 다루지 않고 Indy 기능을 사용할 수 있도록 도와줍니다. 최소한 conceptualy에서, 그것은 추한 해킹이기 때문에 결코 그것을 사용하지 않았습니다.

    스레드를 다루고 싶지 않다면 ICS (link to ICS home page)를 살펴 봐야합니다. ICS는 스레딩없이 비동기 모드에서 사용하도록 설계되었습니다. 차단하지 않기 때문에 TIdAntiFreeze와 동일한 기능이 필요하지 않습니다. 다운로드를 시작하고 진행 및 완료 알림을 받으려면 일부 이벤트를 처리합니다.ICS는 Indy와 마찬가지로 잘 알려져 있고 전문적이며 널리 사용됩니다.

    +0

    스레드를 빙빙 돌리고 나면 그것이 유일한 해결책 인 것 같습니다! 감사. +1 – Ampere

    관련 문제