wxInputStream::GetSize() liefert falschen Wert



  • Hallo!

    Bin gerade dabei ein kleines Updateprogramm zu schreiben und der Download funktioniert auch bereits. Damit das Programm auch optisch ein bisschen was her macht, habe ich einen Ladebalken miteingebaut.Um den Fortschritt ermitteln zu könne brauche ich dazu die Dateigröße. Das Problem ist jetzt, dass wxInputStream::GetSize() einfach 0 zurück liefert und jeder Beispielcode den ich gesehen habe ist grundsätzlich genau so auf gebaut wie dieser hier.

    #include "../include/update.h"
    #include "../include/message.h"
    
    #define MAXBUFFER       128
    #define TIMEOUT         10
    #define USER            "anonymous"
    #define PASS            "anonymous"
    #define TEST_FILE       "blablabla"
    
    void Update::UpdateThread(void *arg){
    
        Update *app = static_cast<Update*>(arg);
        unsigned int i;
        unsigned int counter = 1;
        FILE *out;
        size_t FileSize;
        char buffer[MAXBUFFER];
        char bytes[100];
        char tmp[10];
        char FileSize_str[10];
    
        app->ftp->SetDefaultTimeout(TIMEOUT);
        app->ftp->SetUser(USER);
        app->ftp->SetPassword(PASS);
    
        if(!app->ftp->Connect(URL)){
            app->Message = new wxMessageDialog(app->fMain, wxT(ERROR01_TEXT), wxT(ERROR_TITLE), wxOK | wxICON_ERROR);
            app->Message->ShowModal();
            delete app->Message;
            app->fMain->~MainWindow();
        }
    
        if(!app->ftp->FileExists(TEST_FILE)){
            app->Message = new wxMessageDialog(app->fMain, wxT(ERROR02_TEXT), wxT(ERROR_TITLE), wxOK | wxICON_ERROR);
            app->Message->ShowModal();
            delete app->Message;
            app->fMain->~MainWindow();
        }
        /*app->in ist vom Typ wxInputStream*/
        app->in = app->ftp->GetInputStream(TEST_FILE);
        if(app->in == NULL){
            app->Message = new wxMessageDialog(app->fMain, wxT(ERROR02_TEXT), wxT(ERROR_TITLE), wxOK | wxICON_ERROR);
            app->Message->ShowModal();
            delete app->Message;
            app->fMain->~MainWindow();
        }
    
        out = fopen(TEST_FILE,"wb");
        if(out == NULL){
            app->Message = new wxMessageDialog(app->fMain, wxT(ERROR04_TEXT), wxT(ERROR_TITLE), wxOK | wxICON_ERROR);
            app->Message->ShowModal();
            delete app->Message;
            app->fMain->~MainWindow();
        }
    
        /*Dateigröße ermitteln, was nicht so ganz klappt*/
        FileSize = app->in->GetSize();
    
        itoa(FileSize,FileSize_str,10);
        app->fMain->LblSearchUpdate->SetLabel("Updateing...");
        do{
           app->in->Read(buffer,MAXBUFFER);
           for(i = 0; i < MAXBUFFER; i++){
                fputc(buffer[i],out);
                buffer[i] = '\0';
           }
           app->fMain->Processbar->SetValue((counter * MAXBUFFER * 100)/FileSize);
           itoa(((counter * MAXBUFFER * 100)/FileSize),bytes,10);
           strcat(bytes,"%");
           app->fMain->SetTitle(bytes);
           itoa((counter * MAXBUFFER),tmp,10);
           strcpy(bytes,tmp);
           strcat(bytes,"/");
           strcat(bytes,FileSize_str);
           app->fMain->LblInfo->SetLabel(bytes);
           counter ++;
        }while(app->in->LastRead() >= MAXBUFFER);
    
        app->in->Read(buffer,app->in->LastRead());
        for(i = 0; i < app->in->LastRead();i++){
            fputc(buffer[i],out);
            buffer[i] = '\0';
        }
    
        itoa(((counter - 1) * MAXBUFFER + app->in->LastRead()),tmp,10);
        strcpy(bytes,tmp);
        strcat(bytes,"/");
        strcat(bytes,FileSize_str);
        app->fMain->LblInfo->SetLabel(bytes);
        app->fMain->Processbar->SetValue(100);
    
        fclose(out);
        app->in->~wxInputStream();
        app->ftp->Close();
    }
    

    Ich hoffe einer kann helfen.



  • Dazu fallen mir tausend Gründe ein, für den Anfang wäre ich dafür :

    1. Poste mal mehr Code pls, zumindest noch "update.h"

    2. Wo steht deine Build-/Systemumgebung ? - Zumindest für ältere wxWidgets-Versionen ( 2.6.0 / 2.8.x? ) liefert GetSize() nicht für alle "Streamarten" einen gültigen Wert. Am besten schau dir mal das Changelog an, in der 2.9.x wurden der FSHandler hinzugefügt, etc. ...

    3. Über Code-Stil will ich jetzt nicht streiten, aber sauber ist er nicht, wer weiß was da noch fürn Wurm drin stecken kann.

    4. Oh ja Threads ... und dann noch mit wxWidgets. Du bist mutig ...
    4.1. wxWidgets-Gui-Code ist nicht Multithreading-fähig !
    4.2. Wenn man Gui-Code aus verschiedenen Threads benutzen will, sollte man die entsprechenden Mutexe (etc.) verwenden.

    Ich sehe hier nix davon, würde mich nicht wundern wenn GetSize() sogar das richtige zurückliefert und nur der Balken nicht richtig funktioniert.

    Insbesondere seh ich in der Do-Schleife "kein explizites Update?" !

    Fragen über Fragen

    nurF



  • Der Thread ist bei mir eine static void methode in der klasse update, wird mit CreateThread() aufgerufen und ist sowieso der einzige Thread der in diesen Programm laufen wird, deshalb sind mutexe eigentlich überflüssig. Das Ergebnis was mir GetSize() zurück liefert habe ich ausgegeben und es war immer 0.

    Für Verbesserungvorschläge bin ich immer offen!!

    //update.h
    
    #ifndef __UPDATE_H__
    #define __UPDATE_H__
    
    #include "main_window.h"
    #include <wx/protocol/ftp.h>
    
    class Update : public wxEvtHandler{
    
        public:
            Update() : wxEvtHandler(){
                fMain = new MainWindow(NULL);
                fMain->Show(); 
                ftp = new wxFTP();                                
                UThread = CreateThread(0,0,(LPTHREAD_START_ROUTINE) UpdateThread,static_cast<void*>(this),0,0);
            }
    
            virtual ~Update();
        private: 
            static void UpdateThread(void *arg);  
            wxFTP *ftp;  
            HANDLE UThread;   
            MainWindow *fMain;             
    
        protected:  
            wxInputStream *in;             
            wxMessageDialog *Message;
    
    };
    
    #endif
    

  • Mod

    Hm, ne wenn du GUI Elemente hast, sind das schon mal 2 Threads.
    Und dann darf der 2. Thread nicht auf die GUI Elemente zugreifen, die gehören in wxWidgets immer dem Hauptthread.

    phlox



  • Punkt 2 und 4 sind immer noch offen.
    Aus deiner kurzen Antwort sehe ich eine Bestätigung für Punkt 3.



  • na toll und was jetzt??

    Das Problem ist, dass ich mit mutexe eigentlich noch nicht gearbeitet habe, sondern nur weiß was sie bewirken. Die Version dürfte übrigens passen.


  • Mod

    Stony92 schrieb:

    na toll und was jetzt??

    Das Problem ist, dass ich mit mutexe eigentlich noch nicht gearbeitet habe, sondern nur weiß was sie bewirken. Die Version dürfte übrigens passen.

    Du solltest einfach von deinem Thread aus nicht auf die GUI Elemente zu greifen.
    Am einfachsten wäre es einen wxThread zu erstellen, der dann die Werte per Event an den Hauptthread schickt.



  • nurf schrieb:

    2. Wo steht deine Build-/Systemumgebung ? - Zumindest für ältere wxWidgets-Versionen ( 2.6.0 / 2.8.x? ) liefert GetSize() nicht für alle "Streamarten" einen gültigen Wert. Am besten schau dir mal das Changelog an, in der 2.9.x wurden der FSHandler hinzugefügt, etc. ...

    nurF

    Wie er schon richtig geschrieben hat, wurden gewisse Teile u.a. wxFileSystem komplett überarbeitet. So wird der entsprechende Stream, ob nun HTTP, FTP, ...
    automatisch gepuffert, so daß GetSize() nun immer einen gültigen Wert zurückliefert.

    Offensichtlich nutzt du noch eine ältere wxWidgets-Version, da wxFTP definitiv outdated ist !

    Wer lesen kann, ist klar im Vorteil ...

    wxWidgets-Guru



  • Zu den wxWidgets Versionen sollte man noch folgendes erwähnen:

    Die letzte 'stabile' Version ist 2.8.7 (vom 17.11.2007)
    Version 2.9 ist (wie alle ungeraden Versionsnummern) noch in der Testphase und man muss damit rechnen, dass einige Sachen noch nicht richtig funktionieren oder sich noch stark ändern.

    Ich weiss jetzt nicht, wie weit die aktuelle 2.9 ist und ob man damit schon vernünftig arbeiten kann (Feedback ist willkommen) würde aber keinem, der noch 2.8 nutzt unbedingt sagen, dass seine Version veraltet ist und er auf 2.9 upgraden soll.


  • Mod

    Gordon73 schrieb:

    Zu den wxWidgets Versionen sollte man noch folgendes erwähnen:

    Die letzte 'stabile' Version ist 2.8.7 (vom 17.11.2007)
    Version 2.9 ist (wie alle ungeraden Versionsnummern) noch in der Testphase und man muss damit rechnen, dass einige Sachen noch nicht richtig funktionieren oder sich noch stark ändern.

    Ich weiss jetzt nicht, wie weit die aktuelle 2.9 ist und ob man damit schon vernünftig arbeiten kann (Feedback ist willkommen) würde aber keinem, der noch 2.8 nutzt unbedingt sagen, dass seine Version veraltet ist und er auf 2.9 upgraden soll.

    Wie du schon sagst, sind i.d.R. die ungeraden Versionsnummern bei wxWidgets unstable, d.h. sie werden nie released werden als stable.
    Die Nächste Version wird also 3.0 sein, evtl. aber auch 2.8.8. Mit 3.0 ist evtl. "schon" im Herbst zu rechnen.

    phlox


Anmelden zum Antworten