• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            牽著老婆滿街逛

            嚴以律己,寬以待人. 三思而后行.
            GMail/GTalk: yanglinbo#google.com;
            MSN/Email: tx7do#yahoo.com.cn;
            QQ: 3 0 3 3 9 6 9 2 0 .

            如何從Internet上有效而穩定地下載文件

            作者:hangwire下載本文源程序

            ?如何從Internet上有效而穩定地下載文件 ,這是很多網絡應用程序要考慮的重要問題,本文提供的代碼段針對這個問題進行了初步的探索。希望能夠拋磚引玉,對各位編程人員有所幫助。

            ?UINT InternetGetFile (HINTERNET IN hOpen,
            CHAR *szUrl,
            CHAR *szFileName,
            HWND hwndProgress,
            int idStatusText,
            int idProgressBar);

            這里返回值的類型為UINT,如果成功返回0,否則返回非零值。為了使用這個函數,只需要提供一個有效的HINTERNET句柄,這個句柄可以通過標準的InternetOpen()掉用來獲得。如果你愿意的話,你還可以將一個句柄提供給進度窗口(ID為一靜態控制的標示符,用來顯示狀態),在這個函數的頭幾行代碼中聲明一些變量。

            ?DWORD dwSize;
            這個變量被用于存儲每次調用InternetReadFile讀取了多少數據。

            ?CHAR szHead[] = "Accept: */*\r\n\r\n";
            用于存儲多個HTTP頭信息。如果在調用InternetOpenUrl時不傳遞著個頭信息,則只允許你打開文本文件!

            ?VOID* szTemp[16384];
            緩沖變量,可以存儲來自Internet的16KB的文件數據。

            ?HINTERNET hConnect;
            這是一個HINTERNET句柄,包含請求結果(來自InternetOpenUrl)

            ?FILE * pFile;
            標準的C文件句柄(必須包含stdio.h)。如果你愿意,可以使用Win32處理文件的API

            ?if (!(hConnect = InternetOpenUrlA (hOpen, szUrl, szHead, lstrlenA (szHead), INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_RELOAD, 0)))
            {
            return INTERNET_ERROR_OPENURL;
            }
            ?此調用可以打開一個使用URL的Internet文件句柄。標志表示這個文件總是被讀取,而不是緩存(cache)。如果失敗,則此函數返回錯誤,你可以給定INTERNET_ERROR_OPENURL任何值。必須為這個函數定義所有的錯誤信息。也可以用一個數字替代。

            ?if(!(pFile = fopen(szFileName, "wb" )))
            {
            return INTERNET_ERROR_FILEOPEN;
            }
            此調用根據給定的文件名打開文件。如果失敗則返回另一個用戶定義的錯誤。

            ?DWORD dwByteToRead = 0;
            DWORD dwSizeOfRq = 4;
            DWORD dwBytes = 0;
            這三個值分別存儲文件的大小,HttpQueryInfo內容的大小和總共讀取的字節數。

            ?if (!HttpQueryInfo(hConnect, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, (LPVOID)&dwByteToRead, &dwSizeOfRq, NULL))
            {
            dwByteToRead = 0;
            }
            此調用可以獲得文件的大小。如果失敗則dwByteToRead被置為0,并且當文件被下載時不會顯示百分比和總數

            ?DWORD start;
            DWORD end;
            DWORD time;
            time = 10;
            start = timeGetTime();
            使用這些bit必須包含mmsystem.h并鏈接winmm.lib,它們用于時間選擇,告訴用戶下載的速度。例子代碼只統計了下載速度,你可以擴展這個功能,比如估計還剩多少時間。

            ?do
            {
            if (!InternetReadFile(hConnect, szTemp, 16384, &dwSize))
            {
            fclose (pFile);
            return INTERNET_ERROR_READFILE;
            }
            此調用循環中,每次下載一個16KB的數據塊。如果download請求失敗,則文件被關閉并返回錯誤。

            ?if (!dwSize)
            break;
            else
            fwrite(szTemp, sizeof(char), dwSize, pFile);
            如果dwSize為0,則意味著一個EOF,循環退出。否則由InternetReadFile讀取的數據內容被寫到本地文件中。

            ?dwBytes+=dwSize;
            if(dwByteToRead && hwndProgress)
            {
            SendDlgItemMessageA(hwndProgress, idProgressBar, WM_USER+2, (dwBytes*100)/dwByteToRead, 0);
            UpdateWindow(hwndProgress);
            }
            這個代碼中,dwBytes是從文件讀取的數據量,它不斷增加,如果文件長度是有效的,則進度窗口句柄被指定,進度條被更新已表示下載進度。

            ?FLOAT fSpeed = 0;
            fSpeed = (float)dwBytes;
            fSpeed /= ((float)time)/1000.0f;
            fSpeed /= 1024.0f;
            這些bit代碼用于根據所花時間計算下載速度和讀取的數據量。

            ?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);
            }
            設置和處理進度窗口的狀態文本,表示下載的文件大小和下載速度。

            ?end = timeGetTime();
            time = end - start;
            if(time == 0)
            time = 10;

            時間被更新

            } // do
            while (TRUE);

            循環結束
            fflush (pFile);
            fclose (pFile);
            return 0;
            }
            最后,函數結束,關閉文件并清除硬件驅動的緩沖。返回0表示成功。

            ?使用這個代碼段,按照本文所描述的那樣,你可以自己編寫一個程序來從Internet上有效地、穩定地下載文件。實現細節請參見例子。

            posted on 2006-06-20 18:55 楊粼波 閱讀(594) 評論(5)  編輯 收藏 引用 所屬分類: 文章收藏

            評論

            # re: 如何從Internet上有效而穩定地下載文件 2008-01-25 17:55 @王一偉

            請問用winnet怎么實現遠程的seek操作

            而不是像MFC的HTTPFile那樣down到本地了才Seek

            呵呵 sunraiing@126.com  回復  更多評論   

            # re: 如何從Internet上有效而穩定地下載文件[未登錄] 2008-01-27 20:25 楊粼波

            如果支持斷點續傳,
            都是在服務器上進行Seek的.  回復  更多評論   

            # re: 如何從Internet上有效而穩定地下載文件 2008-01-27 21:45 王一偉

            其實倒不必,如果使用socket的話 可以直接自己封裝http頭字串 在里面添加range 這個項目 就可以進行遠程seek了,但是不清楚winnet對這個是怎么包裝的  回復  更多評論   

            # re: 如何從Internet上有效而穩定地下載文件[未登錄] 2008-01-28 13:48 楊粼波

            原理反正就是擺在那里的,都是差不多的,無非是實現的穩定性問題.
            我以前也想自己實現,但是其穩定性是不能保證的,
            而事務處理本身就會有不穩定的問題存在,
            如果還自己去封裝增加風險是不值得的.
            在windows平臺下還是用Winnet吧,
            若是沒有記錯,HTTPFile也是基于Winnet的.
            我給你找找資料吧.  回復  更多評論   

            # re: 如何從Internet上有效而穩定地下載文件 2008-01-29 12:44 @王一偉

            是的 無外乎就是這樣的  回復  更多評論   

            94久久国产乱子伦精品免费 | 亚洲午夜无码久久久久小说| 亚洲?V乱码久久精品蜜桃| 色综合久久综合中文综合网| 久久www免费人成看国产片| 亚洲成色WWW久久网站| 日本精品久久久久中文字幕| 久久亚洲AV成人无码国产 | 伊人久久久AV老熟妇色| 国产精品九九九久久九九| 亚洲精品乱码久久久久久按摩| 国产精品久久久久久久久| 97香蕉久久夜色精品国产| 亚洲中文字幕伊人久久无码| 国产精品久久久久久久 | 久久精品国产99久久久香蕉| 91精品国产综合久久四虎久久无码一级 | 成人久久精品一区二区三区| 久久成人国产精品| 久久综合亚洲欧美成人| 亚洲国产精品无码久久青草 | 日韩电影久久久被窝网| 91久久精品91久久性色| 亚洲国产另类久久久精品小说| 久久久久国色AV免费看图片| 国产精品美女久久久免费| 久久精品国产亚洲Aⅴ蜜臀色欲| 青青草原精品99久久精品66| 久久国产欧美日韩精品免费| 国产一区二区久久久| 久久一区二区免费播放| 久久婷婷激情综合色综合俺也去| 欧美精品国产综合久久| 亚洲国产成人精品无码久久久久久综合| 国产精品久久久久久福利漫画| 久久人人妻人人爽人人爽| 99久久国产宗和精品1上映| 国产精品久久新婚兰兰| 久久亚洲AV成人无码软件| 亚洲国产精品无码久久一线| 无码超乳爆乳中文字幕久久|