[c++] Zapis strony internetowej do pliku poprzez wątek

Odpowiedz Nowy wątek
2011-01-08 02:20
0

Hej ;) Chciałbym sobie zrobić programik, który ściąga źródło strony na dysk. Otóż mam listę stron internetowych i liste nazw plików pod jakie ma je zapisać. Ale gdy napiszę to tak, że po naciśnięciu przycisku na formie ma się wykonać pętla w której zapisywane są te strony, cały program staje i trzeba czekać aż się wykona do końca.
Pomyślałem, żeby zrobić to w wątku. Jednak napotkałem problem... w wątku nie zapisuje tych stron! ;/. zapisze pierwszą która jest mała i ma 14KB ale druga co ma już 90 - nie.
kod z wątkiem wygląda mniej wiecej tak:

#include <vcl.h>
#include <urlmon.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;

DWORD WINAPI FunkcjaWatku(PVOID pvParam)
{
    for(int i = 1; i < Form1->Memo1->Lines->Count; i++)
    {
        DWORD IdWatku;
        AnsiString aFileName = "C:\\" + Form1->Memo2->Lines->Strings[i];
        char *cFileName = aFileName.c_str();
        AnsiString aURL = Form1->Memo1->Lines->Strings[i];
        char *cURL = aURL.c_str();
        HRESULT Rezultat;
        Rezultat = URLDownloadToFile(0, cURL, cFileName, 0, 0);
    }
  return 0;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
        DWORD IdWatku;
        HANDLE hWatek_1 = CreateThread(NULL, 0, FunkcjaWatku, NULL, 0, &IdWatku);
}
//---------------------------------------------------------------------------

Przy tych większych stronach, zmienna Rezultat wynosi jakąś kosmiczną liczbę -2 miliony coś tam ;p

Dlaczego to nie chce tak działać? co robię źle?

Pozostało 580 znaków

2011-01-08 10:14
0

Zajrzyj do winerror.h lub urlmon.h, żeby dowiedzieć się, co ta kosmiczna wartość oznacza.

Następny błąd, który robisz przy okazji, to odwoływanie się do elementów GUI z wątka, bez synchronizacji. Teraz być może to działa bez problemu, ale w innym przypadku, innej konfiguracji takie odwołania są niebezpieczne. I dlaczego używasz funkcji WinAPI do tworzenia wątka, jeśli w VCL-u masz klasę TThread?

Pozostało 580 znaków

2011-01-08 14:09
0

a nie wiedziałem nawet, że jest ;p. Google pokazało to :D, to chciałem użyć tego :).
robiłem też tak ze mialem w tym wątku samo URLDownloadToFile(0, zmienna1, zmienna2, 0,0); ale i tak nie działało jak chcialem. a co z tą synchronizacją?

Pozostało 580 znaków

2011-01-08 14:14
0

Na temat synchronizacji nie napiszę nic, bo... mi się nie chce :P Na tym forum temat był wałkowany milion razy - poszukaj.

Pozostało 580 znaków

2011-01-08 14:18
0

okej ;D dzieki ;)

Pozostało 580 znaków

2011-01-08 16:03
0

hmm... zmienilem na TThread ale i tak nie działa tak jakbym chciał :(. nie rozumiem o co chodzi.

klasa:

class TDownloadPage : public TThread
{
    public:
        TDownloadPage(char*, char*, bool);
        __fastcall ~TDownloadPage(void);
        void __fastcall Execute();
    private:
        char *FileName, *URL;
};

i kod ktory wykonuje (nie patrzcie ze nie przekazuje wartosci URL i FileName do URLFileDownloadTo, nie chcialo mi sie zmieniac) W kazdym razie, nie zapisuje źródła onetu do pliku.

TDownloadPage *DownloadThread1;

TDownloadPage::TDownloadPage(char* _FileName,
                         char* _URL,bool CreateSuspended)
:TThread(CreateSuspended)
{
    //Ustawienia TThreat
    FreeOnTerminate=true; //Usuwa z pamieci po zakonczeniu Execute
    //Rezerwacja pamieci i kopiowanie danych
    FileName = _FileName;
    URL = _URL;
}
//---------------------------------------------------------------------------

__fastcall TDownloadPage::~TDownloadPage()
{
    ShowMessage("Wątek zakończył działanie");
}
//---------------------------------------------------------------------------

void __fastcall TDownloadPage::Execute()
{
    URLDownloadToFile(0, "http://www.onet.pl/", "C:\\plik1.html", 0, 0);
}

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
    DownloadThread1 = NULL;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
    AnsiString aFileName = "C:\\" + Form1->Memo2->Lines->Strings[1];
    char *cFileName = aFileName.c_str();
    AnsiString aURL = Form1->Memo1->Lines->Strings[1];
    char *cURL = aURL.c_str();

    DownloadThread1 = new TDownloadPage(cURL, cFileName, true);
    DownloadThread1->Resume();
}
//---------------------------------------------------------------------------
edytowany 1x, ostatnio: brylcio16, 2011-01-08 16:34

Pozostało 580 znaków

2011-01-08 16:25
0

No dobrze, ale może byś sprawdził, co zwraca URLDownloadToFile.

Pozostało 580 znaków

2011-01-08 16:32
0

URLDownloadToFile zwraca w wątku -2147221020.
Natomiast gdy skopiuje tą sąmą linijke do wątku głównego, i wykonam ta operacje w wątku głównym - zwraca 0.
Nie wiem o co chodzi...

Pozostało 580 znaków

2011-01-08 16:49
0

Hmm, dziwne. Wartość, którą zwraca ta funkcja to MK_E_SYNTAX, średnio mi tu pasuje :/ Weź może na początku Execute wywołaj CoInitializeEx, a na końcu CoUninitialize

Pozostało 580 znaków

2011-01-08 18:29
0

hmm... no dodalem te funkcje i działa ;)

void __fastcall TDownloadPage::Execute()
{
    CoInitializeEx(NULL, COINIT_APARTMENTTHREADED   );//COINIT_APARTMENTTHREADED);
    hr = URLDownloadToFile(0, URL, FileName, 0, 0);
    CoUninitialize();
}

ale strony "http://www.wp.pl/" nie chce sciagnac ;/ (zjamuje 170KB) i pokazuje blad -2146697211. Nie wiem co on oznacza, nie potrafie tego znalezc.

Zauwazylem jeszcze, ze jak dam do jakiegos buttona cos takiego

HRESULT hrr = URLDownloadToFile(0, "http://www.wp.pl/", "C:\\waaap.html", 0, 0);
Button2->Caption = hrr;

to plik w ogole sie nie pokazuje a hrr zwraca 0... ;/

Pozostało 580 znaków

2011-01-08 19:58
0

-2146697211 to INET_E_RESOURCE_NOT_FOUND, co oznacza, że z serwerem lub połączeniem jest coś nie tak. Nie wiem, co może być tego przyczyną.

Może spróbuj ściągnąć stronę przy pomocy InternetOpenUrl i InternetReadFile.

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0