Frage: Dateien von einem Server lokal speichern??
-
Dann stellt unter anderem die WinAPI Funktionen zum Herunterladen über http bereit. Steht in der MSDN im Kapitel WinInet erklärt.
-
MSDN was ist das ?? *sorry*
und könntest du mal ein beispiel posten?
-
Dieser Thread wurde von Moderator/in HumeSikkins aus dem Forum C++ in das Forum WinAPI verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
Siehe: Enabling Internet Functionality
http://msdn.microsoft.com/library/en-us/wininet/wininet/enabling_internet_functionality.asp
-
ich finde mich in dem msdn nicht zurecht
könnte jemand mal einen beispielcode posten um die datei http://eastbourne.ea.funpic.de/test.txt lokal zu speichern?
-
Wieviel zahlst du?
-
Ich hab da mal was rausgekramt. Allerdings muss ich dich warnen!! Als ich das geschrieben war ich noch schlechter als jetzt! Der Code ist ein C - C++ Mischmasch und außerdem entstehen Memory Leaks (durch TerminateThread). Ich war zu faul das ganze neu zu schreiben, aber immmerhin funktioniert es. Ich glaube die Funktionweise sollte klar sein.
#include <process.h> #include <windows.h> #include <wininet.h> #include <iostream> #include <fstream> struct UpdateDaten { std::string Url; std::fstream TempDatei; bool Erfolgreich; bool Fertig; /* Am Anfang false. Wird true sobald die Datei geöffnet wurde. */ int BytesEmpfangen; int DateiGroesse; }; const char *UPDATE_FILENAME = "test.txt"; class Download123 { private: UpdateDaten Daten; bool Geschlossen; /* Am Anfang true */ HANDLE GetThread; /* Handle auf den GetSourceCode-Thread */ static void GetSourceCode(void *was) { UpdateDaten *pDaten = (UpdateDaten*)was; pDaten->Erfolgreich = true; HINTERNET hInternet; /* Handle des WinInet-Browsers */ HINTERNET hWebsite; /* Handle auf die geöffnete Website */ hInternet=InternetOpen("JNTETRI Update", INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0); /* WinInet-Browser definieren */ if (!hInternet) { pDaten->Erfolgreich = false; pDaten->Fertig = true; return; } hWebsite=InternetOpenUrl(hInternet,pDaten->Url.c_str(),NULL,0, INTERNET_FLAG_RELOAD,0); /* URL öffnen */ if (!hWebsite) { InternetCloseHandle(hInternet); pDaten->Erfolgreich = false; pDaten->Fertig = true; return; } pDaten->DateiGroesse = 0; { char DateiGroesseTemp[10]; DWORD HttpQueryInfoBytes = sizeof(DateiGroesseTemp); if(!HttpQueryInfo(hWebsite,HTTP_QUERY_CONTENT_LENGTH, (void*)&DateiGroesseTemp,&HttpQueryInfoBytes, NULL)) { InternetCloseHandle(hWebsite); InternetCloseHandle(hInternet); pDaten->Erfolgreich = false; pDaten->Fertig = true; } pDaten->DateiGroesse = atoi(DateiGroesseTemp); } { char StatusCode[10]; DWORD HttpQueryInfoBytes = sizeof(StatusCode); if(!HttpQueryInfo(hWebsite,HTTP_QUERY_STATUS_CODE, (void*)&StatusCode,&HttpQueryInfoBytes, NULL) || atoi(StatusCode) >= 400) { InternetCloseHandle(hWebsite); InternetCloseHandle(hInternet); pDaten->Erfolgreich = false; pDaten->Fertig = true; } } if(pDaten->DateiGroesse == 0) { InternetCloseHandle(hInternet); pDaten->Erfolgreich = false; pDaten->Fertig = true; return; } pDaten->BytesEmpfangen = 0; char TempDateiname[] = "Download.temp"; pDaten->TempDatei.open(TempDateiname, std::ios_base::out | std::ios_base::binary); DWORD bytesRead; /* Wird beim einlesen verwendet */ char recvBytes[1024]; while (pDaten->BytesEmpfangen < pDaten->DateiGroesse) { if (InternetReadFile(hWebsite,(LPVOID)recvBytes,sizeof(recvBytes),&bytesRead)) { pDaten->BytesEmpfangen += bytesRead; pDaten->TempDatei.write(recvBytes, bytesRead); } else { pDaten->Erfolgreich = false; break; } } InternetCloseHandle(hWebsite); /* Handles wieder schließen */ InternetCloseHandle(hInternet); pDaten->TempDatei.close(); if(!MoveFileEx(TempDateiname,UPDATE_FILENAME,MOVEFILE_REPLACE_EXISTING)) { pDaten->Erfolgreich = false; } pDaten->Fertig = true; } public: Download123() { Geschlossen = true; Daten.Fertig = false; GetThread = NULL; Daten.DateiGroesse = 0; Daten.BytesEmpfangen = 0; } ~Download123() { if(GetThread != NULL) { TerminateThread(GetThread,0); } } void OeffneDatei(std::string was) { Geschlossen = false; Daten.Fertig = false; Daten.Url = was; GetThread = (HANDLE)_beginthread(GetSourceCode,0,(void*)&Daten); } void SchliesseDatei() { Geschlossen = true; TerminateThread(GetThread,0); GetThread = NULL; } bool Geoeffnet() { if(Geschlossen) { return false; } return Daten.Fertig; } bool Erfolgreich() { return Daten.Erfolgreich; } int DateiGroesse() { return Daten.DateiGroesse; } int BytesEmpfangen() { return Daten.BytesEmpfangen; } }; int main() { Download123 d; d.OeffneDatei("http://eastbourne.ea.funpic.de/test.txt"); while(!d.Geoeffnet()) { Sleep(1000); std::cout << "Lade... " << d.BytesEmpfangen() << " von " << d.DateiGroesse() << std::endl; } std::cout << "Fertig!\n"; system("PAUSE"); }mfg.
-
joomoo schrieb:
Als ich das geschrieben war ich noch schlechter als jetzt! Der Code ist ein C - C++ Mischmasch und außerdem entstehen Memory Leaks (durch TerminateThread).
Au backe... "TerminateThread" sollte man nie aufrufen!
Siehe: Why you should never call Suspend/TerminateThread (Part I-III)
http://blog.kalmbachnet.de/?postid=6
http://blog.kalmbachnet.de/?postid=16
http://blog.kalmbachnet.de/?postid=17
-
Jochen Kalmbach schrieb:
joomoo schrieb:
Als ich das geschrieben war ich noch schlechter als jetzt! Der Code ist ein C - C++ Mischmasch und außerdem entstehen Memory Leaks (durch TerminateThread).
Au backe... "TerminateThread" sollte man nie aufrufen!
Und warum nicht? -> Weil da unter anderem Memory Leaks entstehen. Und was hab ich geschrieben? Das mein Code wirklich "au backe..." ist, weil ich terminatethread benutze. Ich sagte doch dass der Code schlecht ist. Aber immerhin hab ich ihn gepostet. Er kann es ja umschreiben.
Ich bin mir schon bewusst dass dies Kacke ist! Aber hier ne Lösung wie du das ganze umschreibst: Ersetze das TerminateThread durch ein schließén der beiden Handles.
mfg.
-
joomoo schrieb:
Und warum nicht? -> Weil da unter anderem Memory Leaks entstehen.
Memory-Leaks sind nicht "so" schlimm... aber es kann vorkommen das Deine ganze Anwendung nicht mehr tut...
-
Jochen Kalmbach schrieb:
joomoo schrieb:
Und warum nicht? -> Weil da unter anderem Memory Leaks entstehen.
Memory-Leaks sind nicht "so" schlimm... aber es kann vorkommen das Deine ganze Anwendung nicht mehr tut...
Ja aber ich hab ja jetzt keine CriticalSection. Naja ich weiß dass dies schlecht ist, aber das ist noch von früher, heute würde ich es wieso mit den boost::threads machen und ich glaube da gibt's so eine böse funktion gar nicht.
mfg.
-
Es kommt ja nicht darauf an, ob Du Critical-Sections hast... wenn Du die WinAPI oder die CRT verwendest, gibt es da noch ne menge andere die sowas haben...
Aber wie Du gesagt hast: der Code dient als Anhaltspunkt...
-
erstmal ein dickes DANKE

jetzt habe ich wenigstens schon mal was

Allerdings noch ein Problem habe ich damit

dev-c++ liefert beim compilieren diverse linker error's zurück
[Linker error] undefined reference to `InternetOpenA@20' [Linker error] undefined reference to `InternetOpenUrlA@24' [Linker error] undefined reference to `InternetCloseHandle@4' [Linker error] undefined reference to `HttpQueryInfoA@20' [Linker error] undefined reference to `InternetCloseHandle@4' [Linker error] undefined reference to `InternetCloseHandle@4' [Linker error] undefined reference to `HttpQueryInfoA@20' [Linker error] undefined reference to `InternetCloseHandle@4' [Linker error] undefined reference to `InternetCloseHandle@4' [Linker error] undefined reference to `InternetCloseHandle@4' [Linker error] undefined reference to `InternetReadFile@16' [Linker error] undefined reference to `InternetCloseHandle@4' [Linker error] undefined reference to `InternetCloseHandle@4' ld returned 1 exit status

-
download123 schrieb:
erstmal ein dickes DANKE

jetzt habe ich wenigstens schon mal was

Allerdings noch ein Problem habe ich damit

dev-c++ liefert beim compilieren diverse linker error's zurück
[Linker error] undefined reference to `InternetOpenA@20' [Linker error] undefined reference to `InternetOpenUrlA@24' [Linker error] undefined reference to `InternetCloseHandle@4' [Linker error] undefined reference to `HttpQueryInfoA@20' [Linker error] undefined reference to `InternetCloseHandle@4' [Linker error] undefined reference to `InternetCloseHandle@4' [Linker error] undefined reference to `HttpQueryInfoA@20' [Linker error] undefined reference to `InternetCloseHandle@4' [Linker error] undefined reference to `InternetCloseHandle@4' [Linker error] undefined reference to `InternetCloseHandle@4' [Linker error] undefined reference to `InternetReadFile@16' [Linker error] undefined reference to `InternetCloseHandle@4' [Linker error] undefined reference to `InternetCloseHandle@4' ld returned 1 exit status

Du musst die WinInet Library linken. SOlltest du dir allgemein mal merken: bei linker errors mit undefined reference isses meistes ne vergessene library.
mfg.