User Tools

Site Tools


downloading_20a_20file_20from_20a_20url

Downloading a file from a URL

by Richard Russell, August 2007; amended July 2009

The simplest method of downloading a file (e.g. a web page) from an internet URL is to use the URLDownloadToFile API function as described in the main documentation. The following program segment illustrates how to do that:

        url$ = "http://www.bbcbasic.co.uk/bbcwin/bbcwin.html"
        file$ = @tmp$+"bbcwin.html"
        PROCurldownload(url$, file$)
        END
 
        DEF PROCurldownload(url$, file$)
        LOCAL urlmon%, res%
        SYS "LoadLibrary", "urlmon.dll" TO urlmon%
        SYS "GetProcAddress", urlmon%, "URLDownloadToFileA" TO `URLDownloadToFile`
        SYS `URLDownloadToFile`, 0, url$, file$, 0, 0 TO res%
        SYS "FreeLibrary", urlmon%
        IF res% ERROR 100, "Couldn't download "+url$
        ENDPROC

If you need to flush the cache to ensure you retrieve the latest version (e.g. it's a webcam picture) then it becomes slightly more complicated:

        url$ = "http://www.bbcbasic.co.uk/bbcwin/bbcwin.html"
        file$ = @tmp$+"bbcwin.html"
        PROCurldownloadflush(url$, file$)
        END
 
        DEF PROCurldownloadflush(url$, file$)
        LOCAL urlmon%, wininet%, res%
        SYS "LoadLibrary", "URLMON.DLL" TO urlmon%
        SYS "GetProcAddress", urlmon%, "URLDownloadToFileA" TO `URLDownloadToFile`
        SYS "LoadLibrary", "WININET.DLL" TO wininet%
        SYS "GetProcAddress", wininet%, "DeleteUrlCacheEntryA" TO `DeleteUrlCacheEntry`
        SYS `DeleteUrlCacheEntry`, url$
        SYS `URLDownloadToFile`, 0, url$, file$, 0, 0 TO res%
        SYS "FreeLibrary", wininet%
        SYS "FreeLibrary", urlmon%
        IF res% ERROR 100, "Couldn't download "+url$
        ENDPROC

These routines can be used for both HTTP and FTP downloads.

However under some circumstances the above methods do not work reliably. In that case you may find the following routine to be more successful:

        url$ = "http://www.bbcbasic.co.uk/bbcwin/bbcwin.html"
        file$ = @tmp$+"bbcwin.html"
        PROCurldownload(url$, file$)
        END
 
        DEF PROCurldownload(url$, file$)
        LOCAL wininet%, buffer%, hinet%, hreq%, file%, nbr%, nbw%, ok%
        DIM buffer% LOCAL 511
 
        _INTERNET_OPEN_TYPE_PRECONFIG = 0
        _INTERNET_FLAG_RELOAD = &80000000
 
        SYS "LoadLibrary", "WININET.DLL" TO wininet%
        SYS "GetProcAddress", wininet%, "InternetOpenA"       TO `InternetOpen`
        SYS "GetProcAddress", wininet%, "InternetOpenUrlA"    TO `InternetOpenUrl`
        SYS "GetProcAddress", wininet%, "InternetReadFile"    TO `InternetReadFile`
        SYS "GetProcAddress", wininet%, "InternetCloseHandle" TO `InternetCloseHandle`
 
        SYS `InternetOpen`, "BB4W", _INTERNET_OPEN_TYPE_PRECONFIG, 0, 0, 0 TO hinet%
        IF hinet% = 0 ERROR 100, "Couldn't open internet services"
 
        SYS `InternetOpenUrl`, hinet%, url$, "", 0, _INTERNET_FLAG_RELOAD, 0 TO hreq%
        IF hreq% = 0 THEN
          PROCinetcleanup
          ERROR 100, "Couldn't open "+url$
        ENDIF
 
        file% = OPENOUT(file$)
        IF file% = 0 THEN
          PROCinetcleanup
          ERROR 100, "Couldn't create "+file$
        ENDIF
 
        REPEAT
          SYS `InternetReadFile`, hreq%, buffer%, 512, ^nbr% TO ok%
          IF ok% = 0 THEN
            PROCinetcleanup
            ERROR 100, "Couldn't read from "+url$
          ENDIF
          SYS "WriteFile", @hfile%(file%), buffer%, nbr%, ^nbw%, 0 TO ok%
          IF ok% = 0 THEN
            PROCinetcleanup
            ERROR 100, "Couldn't write "+file$
          ENDIF
        UNTIL nbr% = 0
 
        CLOSE #file%
 
        PROCinetcleanup
        ENDPROC
 
        DEF PROCinetcleanup
        hreq% += 0  : IF hreq%  SYS `InternetCloseHandle`, hreq%  : hreq% = 0
        hinet% += 0 : IF hinet% SYS `InternetCloseHandle`, hinet% : hinet% = 0
        wininet% += 0 : IF wininet% SYS "FreeLibrary", wininet% : wininet% = 0
        ENDPROC

Unfortunately with early versions of Internet Explorer (pre 4.0) the above code results in a memory leak when used for http downloads (see http://support.microsoft.com/kb/174897). If you need your code to work with such old versions you can use the following routine instead (note that because the HTTP protocol is implied, you must not include the "http://" in the supplied server$):

        server$ = "www.bbcbasic.co.uk"
        request$ = "bbcwin/bbcwin.html"
        file$ = @tmp$+"bbcwin.html"
        PROChttpdownload(server$, request$, file$)
        END
 
        DEF PROChttpdownload(server$, request$, file$)
        LOCAL wininet%, buffer%, hinet%, hsess%, hreq%, file%, nbr%, nbw%, ok%
        DIM buffer% LOCAL 511
 
        _INTERNET_OPEN_TYPE_PRECONFIG = 0
        _INTERNET_DEFAULT_HTTP_PORT = 80
        _INTERNET_SERVICE_HTTP = 3
        _INTERNET_FLAG_RELOAD = &80000000
 
        SYS "LoadLibrary", "WININET.DLL" TO wininet%
        SYS "GetProcAddress", wininet%, "InternetOpenA"       TO `InternetOpen`
        SYS "GetProcAddress", wininet%, "InternetConnectA"    TO `InternetConnect`
        SYS "GetProcAddress", wininet%, "HttpOpenRequestA"    TO `HttpOpenRequest`
        SYS "GetProcAddress", wininet%, "HttpSendRequestA"    TO `HttpSendRequest`
        SYS "GetProcAddress", wininet%, "InternetReadFile"    TO `InternetReadFile`
        SYS "GetProcAddress", wininet%, "InternetCloseHandle" TO `InternetCloseHandle`
 
        SYS `InternetOpen`, "BB4W", _INTERNET_OPEN_TYPE_PRECONFIG, 0, 0, 0 TO hinet%
        IF hinet% = 0 ERROR 100, "Couldn't open internet services"
 
        SYS `InternetConnect`, hinet%, server$, _INTERNET_DEFAULT_HTTP_PORT, \
        \                      "", "", _INTERNET_SERVICE_HTTP, 0, 0 TO hsess%
        IF hsess% = 0 THEN
          PROCinetcleanup
          ERROR 100, "Couldn't connect to "+server$
        ENDIF
 
        SYS `HttpOpenRequest`, hsess%, 0, request$, 0, 0, 0, _INTERNET_FLAG_RELOAD, \
        \                      0 TO hreq%
        IF hreq% = 0 THEN
          PROCinetcleanup
          ERROR 100, "Couldn't open "+request$
        ENDIF
 
        SYS `HttpSendRequest`, hreq%, 0, 0, 0, 0 TO ok%
        IF ok% = 0 THEN
          PROCinetcleanup
          ERROR 100, "Couldn't request "+request$
        ENDIF
 
        file% = OPENOUT(file$)
        IF file% = 0 THEN
          PROCinetcleanup
          ERROR 100, "Couldn't create "+file$
        ENDIF
 
        REPEAT
          SYS `InternetReadFile`, hreq%, buffer%, 512, ^nbr% TO ok%
          IF ok% = 0 THEN
            PROCinetcleanup
            ERROR 100, "Couldn't read "+request$
          ENDIF
          SYS "WriteFile", @hfile%(file%), buffer%, nbr%, ^nbw%, 0 TO ok%
          IF ok% = 0 THEN
            PROCinetcleanup
            ERROR 100, "Couldn't write "+file$
          ENDIF
        UNTIL nbr% = 0
 
        CLOSE #file%
 
        PROCinetcleanup
        ENDPROC
 
        DEF PROCinetcleanup
        hreq% += 0  : IF hreq%  SYS `InternetCloseHandle`, hreq%  : hreq% = 0
        hsess% += 0 : IF hsess% SYS `InternetCloseHandle`, hsess% : hsess% = 0
        hinet% += 0 : IF hinet% SYS `InternetCloseHandle`, hinet% : hinet% = 0
        wininet% += 0 : IF wininet% SYS "FreeLibrary", wininet% : wininet% = 0
        ENDPROC
This website uses cookies for visitor traffic analysis. By using the website, you agree with storing the cookies on your computer.More information
downloading_20a_20file_20from_20a_20url.txt · Last modified: 2018/04/17 15:59 by tbest3112