[ InternetReadFile() ] manche dateien lassen sich saugen, andere nicht...
-
Jetzt ist nur noch das Problem, dass während des Lesens des Files die ganze Anwendung eingefroren wird. Kann man das irgendwie ändern?
-
Threads?
-
Hmm, ok. Klar. Ich wollte nur, da gäbe es eine Callback-Funktion, in der man mitbekommt wieviele Bytes bisher runtergeladen sind. Wegen der Progress-Anzeige, wisst ihr.
-
Wenn man InternetReadFile benutzt ist das doch garkein Problem?
Man kann doch nach jedem Aufruf dieser Funktion die Progress-Bar aktuallisieren.
-
Verstehe ich nicht. In den anderen Aufrufen müsste ich ja angeben können, von wo das File gelesen werden soll. Ich will ja nicht wieder am Anfang beginnen.
-
nein! dafür gibts doch den file pointer. der liest da wo der zeiger drauf gesetzt ist.
-
Verstehe ich nicht so ganz. Sorry. Bin heute auch etwas langsam.
Ich will jetzt z.B. das File ab Position 100 lesen. Wie schreib ich das in InternetReadFile() rein?
-
InternetSetFilePointer(Parameter hab ich jetzt keine Lust rauszusuchen, nur irgendwo 100 angeben :D);
InternetReadFile(immer noch keine Lust);
-
Achso. Woher soll ich denn wissen, dass es dafür eine extra Funktion gibt. Naja, ich wed's mir mal in der MSDN anschauen.
Ist das Ganze nicht vielleicht ein wenig umständlich, wenn man immer wieder die Funktion InternetReadFile() aufruft? Verlängert das nicht die Downloadzeit?
-
na ja InternetSetFilePointer benötigt mal wohl nur zum Resumen oder sowas.
Verlängert das nicht die Downloadzeit?
ja, um 2 ms.
Wenn man lokale Dateien bearbeitet, liest man doch normalweise auch nie die ganze Datei auf einmal ein.
-
Original erstellt von <#>:
na ja InternetSetFilePointer benötigt mal wohl nur zum Resumen oder sowas.Tja, das tue ich ja praktisch, wenn ich immer einzeln Blöcke der Datei lese um nach jedem Block den Progress anzuzeigen.
-
Ich hab da noch ein Problem mit HttpQueryInfo. Also, ich schreibe
DWORD FileSize; DWORD dwDummy = 4; DWORD dwDummy2 = 0; HttpQueryInfo(hFile, HTTP_QUERY_CONTENT_LENGTH, (LPVOID)&FileSize, &dwDummy, &dwDummy2);
Ich setze den ersten Dummy auf 4, weil so groß ja mein Buffer ist. Mit dem letzten Parameter wusste ich nichts anzufangen. Höchstwahrscheinlich liegt es an diesem, warum ich in FileSize nach diesem Aufruf nie die richtige Größe des Files stehen habe. Kann dazu jemand etwas sagen?
<edit> Weitere Info: Die Funktion gibt FALSE zurück. </edit>
[ Dieser Beitrag wurde am 25.01.2003 um 21:39 Uhr von WebFritzi editiert. ]
-
Habs jetzt. Den Pointer auf die Fileposition braucht man ja garnicht! Der wird nach einem Aufruf von InternetReadFile() garnicht zurückgesetzt! Naja, egal. Ich hab mir jetzt mal ne schöne Funktion geschrieben, von der ich denke, dass ihr daran Anteil haben solltet.
#include <windows.h> #include <wininet.h> #include <stdio.h> // For file operations #include <stdlib.h> // For function atoi() // typedef for callback function typedef BOOL (CALLBACK *DOWNLOAD_CALLBACK)(INT*, INT*, LPVOID); // Function ShowLastErrorString // Shows the last error in a messagebox VOID ShowLastErrorString() { LPVOID lpMsgBuf; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR)&lpMsgBuf, 0, NULL ); MessageBox(NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION); LocalFree(lpMsgBuf); } // Function DownloadFile // httpFile : The file to download // targetfile : The file to save httpFile to // lpDownloadCb: A callback function which is called everytime // a percent point more was downloaded // lpInfo : Extra info which is used in lpDownloadCb VOID DownloadFile(LPCTSTR httpFile, LPCTSTR targetFile, DOWNLOAD_CALLBACK lpDownloadCb, LPVOID lpInfo) { HINTERNET hInternet; HINTERNET hFile; HGLOBAL hGlobal; FILE* fFile; CHAR* szBuf; BOOL bGO = TRUE; DWORD dwReadSize = 256; CHAR lpszFileSize[15]; INT iFileSize; INT iStep; INT iDownloadedBytes = 0; DWORD dwDummy; TCHAR szErrBuf[256]; // Initialize internet API and get a handle to internet file hInternet = InternetOpen("WinINet Sample Program", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); if(!hInternet) { ShowLastErrorString(); return; } hFile = InternetOpenUrl(hInternet, httpFile, NULL, 0, INTERNET_FLAG_RELOAD, 0); if(!hFile) { ShowLastErrorString(); InternetGetLastResponseInfo(&dwDummy, szErrBuf, &dwReadSize); MessageBox(NULL, szErrBuf, "Error", MB_OK | MB_ICONINFORMATION); InternetCloseHandle(hInternet); return; } // Get inet file's size dwDummy = 15; HttpQueryInfo(hFile, HTTP_QUERY_CONTENT_LENGTH, (LPVOID)lpszFileSize, &dwDummy, NULL); iFileSize = atoi(lpszFileSize); if(iFileSize == 0) { MessageBox(NULL, "The file you want to download doesn't exist\nor has file size zero", "ERROR", MB_OK|MB_ICONERROR); InternetCloseHandle(hFile); InternetCloseHandle(hInternet); return; } iStep = (iFileSize / 100 == 0) ? 1 : iFileSize / 100; // allocate the fitting amount of memory hGlobal = GlobalAlloc(GMEM_FIXED, iStep + 1); szBuf = (CHAR*)GlobalLock(hGlobal); // Download the file fFile = fopen(targetFile, "w+b"); while(bGO) { bGO = InternetReadFile(hFile, szBuf, iStep, &dwReadSize); if(bGO && dwReadSize == 0) break; szBuf[dwReadSize] = '\0'; fwrite(szBuf, 1, dwReadSize, fFile); iDownloadedBytes = iDownloadedBytes + iStep; if(lpDownloadCb) if( lpDownloadCb(&iFileSize, &iDownloadedBytes, lpInfo) == FALSE) break; } fclose(fFile); // Clean up and close handles GlobalUnlock(hGlobal); GlobalFree(hGlobal); InternetCloseHandle(hFile); InternetCloseHandle(hInternet); }
[ Dieser Beitrag wurde am 26.01.2003 um 00:07 Uhr von WebFritzi editiert. ]
-
gut!!![/
-
Was sollte der letze Post schon wieder. Echt.
-
Hä? Ich hab doch WebFritzi nur mal gelobt. Darf man das etwa nicht?
-
Na klar darfst du das.
-
Klar. Aber was soll das, keinen Namen anzugeben, und dann solche beschrenkte Posts wie:
Original erstellt von < >:
gut!!![/Najo gut, jedem selber überlassen. *G*
Fritzi, Dein Code ist guet, guet fürs FAQ. Solltest das eigentlich Filedownload aber in einen Threadpacken, oder die message Peeken!
-
Hab das schon in nen Thread gepackt. Bloß in VCL. Das geht einfacher. Mit den Thread-Funktionen der WinAPI kenne ich mich nicht so gut aus.
Das mit dem Thread läuft wunderbar. Nur... (auch ohne Thread): Wenn ich auf DOWNLOAD klicke, dann fängt er manchmal erst nach einer Minute an zu downloaden. Manchmal geht's aber auch sofort los. Woran kann das liegen? Es passiert im Aufruf von InternetOpen() oder InternetOpenUrl().
-
Ich meinte bühsen oder so. Weiß ned wie das geschrieben wird.