How to effectively and stably download files from the Internet is an important issue for many network applications. The code segment provided in this article explores this issue. I hope to help programmers.
UINT InternetGetFile (hinternet in hOpen,
CHAR * szUrl,
CHAR * szFileName,
HWND hwndProgress,
Int idStatusText,
Int idProgressBar );
Here, the type of the returned value is UINT. If the return value is successful, 0 is returned. Otherwise, a non-zero value is returned. To use this function, you only need to provide a valid HINTERNET handle, which can be obtained through standard InternetOpen. If you want to, you can also provide a handle to the Progress window (ID is a static control identifier used to display the status ), declare some variables in the first few lines of code of this function.
DWORD dwSize;
This variable is used to store how much data is read by calling InternetReadFile each time.
CHAR szHead [] = "Accept :*/*";
Stores multiple HTTP headers. If no header information is transmitted when InternetOpenUrl is called, you can open a text file only!
VOID * szTemp [2, 16384];
Buffer variable, which can store 16 KB of file data from the Internet.
HINTERNET hConnect;
This is an HINTERNET handle that contains the request result (from InternetOpenUrl)
FILE * pFile;
Standard C file handle (must contain stdio. h ). If you want to, you can use the Win32 API to process files.
If (! (HConnect = InternetOpenUrlA (hOpen, szUrl, szHead, lstrlenA (szHead), INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_RELOAD, 0 )))
{
Return INTERNET_ERROR_OPENURL;
}
This call can open an Internet file handle using a URL. Indicates that the file is always read, not cached ). If this function fails, an error is returned. You can specify any value of INTERNET_ERROR_OPENURL. All error messages must be defined for this function. It can also be replaced by a number.
If (! (PFile = fopen (szFileName, "wb ")))
{
Return INTERNET_ERROR_FILEOPEN;
}
This call opens a file based on the given file name. If it fails, another user-defined error is returned.
DWORD dwByteToRead = 0;
DWORD dwSizeOfRq = 4;
DWORD dwBytes = 0;
These three values respectively store the file size, the size of HttpQueryInfo content, and the total number of bytes read.
If (! HttpQueryInfo (hConnect, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, (LPVOID) & dwByteToRead, & dwSizeOfRq, NULL ))
{
DwByteToRead = 0;
}
This call can obtain the file size. If the download fails, dwByteToRead is set to 0, and the percentage and total number are not displayed when the file is downloaded.
DWORD start;
DWORD end;
DWORD time;
Time = 10;
Start = timeGetTime ();
To use these bits, you must include mmsystem. h and link winmm. lib. These bits are used for time selection to indicate the download speed. The sample code only counts the download speed. You can extend this function, for example, estimate the remaining time.
Do
{
If (! InternetReadFile (hConnect, szTemp, 16384, & dwSize ))
{
Fclose (pFile );
Return INTERNET_ERROR_READFILE;
}
In this call loop, a 16 KB data block is downloaded each time. If the download request fails, the file is closed and an error is returned.
If (! DwSize)
Break;
Else
Fwrite (szTemp, sizeof (char), dwSize, pFile );
If dwSize is 0, it means an EOF, And the loop exits. Otherwise, the data read by InternetReadFile is written to the local file.
DwBytes + = dwSize;
If (dwByteToRead & hwndProgress)
{
SendDlgItemMessageA (hwndProgress, idProgressBar, WM_USER + 2, (dwBytes * 100)/dwByteToRead, 0 );
UpdateWindow (hwndProgress );
}
In this Code, dwBytes is the amount of data read from the file. It increases constantly. If the file length is valid, the Progress window handle is specified, and the progress bar is updated to indicate the download progress.
FLOAT fSpeed = 0;
FSpeed = (float) dwBytes;
FSpeed/= (float) time)/1000.0f;
FSpeed/= 1024366f;
These bit codes are used to calculate the download speed and data size based on the time spent.
If (hwndProgress)
{
Char s [260];
Sprintf (s, "% d KB/% d KB @ % 1.1f KB/s", dwBytes/1024, dwByteToRead/1024, fSpeed );
SetDlgItemTextA (hwndProgress, idStatusText, s );
UpdateWindow (hwndProgress );
}
Sets and processes the status text in the Progress window, indicating the size and speed of the downloaded file.
End = timeGetTime ();
Time = end-start;
If (time = 0)
Time = 10;
Time updated
} // Do
While (TRUE );
Loop ends
Fflush (pFile );
Fclose (pFile );
Return 0;
}
Finally, the function ends, closes the file, and clears the buffer of the hardware driver. If the return value is 0, the operation is successful.