Guybrush Threepwood Geschrieben 9. Dezember 2002 Geschrieben 9. Dezember 2002 Hi, ich hab ein Programm das eine Datei von einem Webserver auf die Festplatte kopiert, dazu wird in einer Schleife, bis das Dateiende erreicht ist, mit InternetReadFile() ein Zeichen aus der Datei gelsesen und in die Datei auf der Festplatte gespeichert, jedesmal wenn ein hunderstel der Datei kopiert wurde wird eine Progressbar erweitert. Allerdings dauert der kopiervorgang sehr,sehr lange. Ich dachte das das vielleicht daran liegt das immer nur ein Zeichen gelesen wird, wenn ich aber mehr lese ist die Datei immer fehlerhaft. Es gibt zwar funktionendie die Datei komplett und schneller kopieren würden, aber dann hätte ich ja nicht die Progressbar die anzeigt wie weit man ist. Hat irgendwer ne Idee wie man die Datei schneller kopieren könnte? Gruß Guybrush Zitieren
Klotzkopp Geschrieben 9. Dezember 2002 Geschrieben 9. Dezember 2002 Originally posted by Guybrush Threepwood Ich dachte das das vielleicht daran liegt das immer nur ein Zeichen gelesen wirdDaran liegt es mit Sicherheit, denn dadurch wird für jedes einzelne Byte eine Anfrage an den Webserver geschickt , wenn ich aber mehr lese ist die Datei immer fehlerhaft.Sollte eigentlich nicht sein. Zeig doch bitte mal den entsprechenden Code. Es gibt zwar funktionen die die Datei komplett und schneller kopieren würden, aber dann hätte ich ja nicht die Progressbar die anzeigt wie weit man ist.Du könntest die Datei aber in größeren Stücken herunterladen, wobei die Anzahl der Fragmente von der Dateigröße abhängt. Zitieren
Guybrush Threepwood Geschrieben 9. Dezember 2002 Autor Geschrieben 9. Dezember 2002 Ich habs mal gerade für 1000 Zeichen geändert und es kommt immer ne Fehlermeldung: Damage after block sowieso Hier ist die Schleife: while(dwRead != NULL) //Status = Null wenn InternetReadFile am Ende der Datei { if (InternetReadFile(hFile,&c,1000,&dwRead) == FALSE) //1 Zeichen aus der Quelldatei lesen { Fehler("Von der Quelldatei konnte nicht gelesen werden.",GetLastError()); SendMessage(hMainWindow,WM_CLOSE,0,0); } if (dwRead != NULL) { //putc(c,stream); //Das Zeichen in die Zieldatei schreiben fprintf(stream,"%s",c); i+=1000; //Zähler erhöhen if (i % o == 0) //Wenn 1/100 geschrieben { SendMessage(hProgress,PBM_STEPIT,0,0); //Progressbar um einen Schritt weiter } } } [/PHP] Zitieren
Klotzkopp Geschrieben 9. Dezember 2002 Geschrieben 9. Dezember 2002 Originally posted by Guybrush Threepwood if (InternetReadFile(hFile,&c,1000,&dwRead) == FALSE) //1 Zeichen aus der Quelldatei lesenIst c ein char-Array? Dann darf da nicht die Adresse verwendet werden. fprintf(stream,"%s",c);Das ist problematisch, weil fprintf mit %s einen nullterminierten String erwartet. Selbst wenn Du c mit einem Nullbyte abgeschlossen hast, können Fehler auftreten, wenn mittendrin ein Nullbyte steht, was bei Binärdateien vorkommen kann. fwrite wäre hier richtig. Zitieren
Guybrush Threepwood Geschrieben 9. Dezember 2002 Autor Geschrieben 9. Dezember 2002 Ok, ich hab das jetzt geändert, aber jetzt bekomme ich eine Accessviolation in funktion memcpy(). Zitieren
Klotzkopp Geschrieben 9. Dezember 2002 Geschrieben 9. Dezember 2002 Wofür brauchst Du memcpy? Zitieren
Guybrush Threepwood Geschrieben 9. Dezember 2002 Autor Geschrieben 9. Dezember 2002 Keine Ahnung ich nehme an das fwrite diese Funktion verwendet, aber den Fehler habe ich jetzt behoben, ich hatte bei der Anzahl der zu schreibenden Zeichen bei fwrite die Funktion strlen() benutzt, aber das ist ja das selbe Problem wie bei fprintf(). Ich hab da jetzt dwRead(also die Anzahl der gelesenen Zeichen) reingeschrieben. Jetzt kommt wieder die Fehlermeldung "Damage: after normal Block (#55)....". Zitieren
Klotzkopp Geschrieben 9. Dezember 2002 Geschrieben 9. Dezember 2002 Originally posted by Guybrush Threepwood "Damage: after normal Block (#55)....". Das ist ein Indiz für einen Pufferüberlauf. Wieviel Speicher hast Du denn für c geholt? Zitieren
Guybrush Threepwood Geschrieben 9. Dezember 2002 Autor Geschrieben 9. Dezember 2002 c ist als char c[1000]; deklariert. Wenn ich jetzt anstatt 1000 nur 100 Zeichen lese kommt der Fehler später, an einem Pufferüberlauf kann es ja eigentlich nicht liegen, weil die Zeichen werden ja nicht an c angefügt sondern neu reinkopiert. Zitieren
Guybrush Threepwood Geschrieben 9. Dezember 2002 Autor Geschrieben 9. Dezember 2002 Mir ist gerade aufgefallen, dass wenn ich das Programm im Debugmodus starte, an der Stelle wo fwrite aufgerufen wird jedesmal eine Warnung "Accessviolation" im Debugfenster erscheint, ohne das ein Error auftritt. Zitieren
Klotzkopp Geschrieben 9. Dezember 2002 Geschrieben 9. Dezember 2002 Wie sieht denn der fwrite-Aufruf aus? Zitieren
Guybrush Threepwood Geschrieben 9. Dezember 2002 Autor Geschrieben 9. Dezember 2002 fwrite(c,sizeof©,dwRead,stream); ich hab aber gerade gesehen dass in der msdn libraray und auf der Microsoft Homepage der Aufruf so aussieht: size_t fwrite( const void *buffer, size_t size, size_t count, FILE *stream ); aber in allen Beispielen der MSDN Library so verwendet wird: size_t fwrite( const void *buffer, size_t count, size_t size, FILE *stream ); was stimmt denn nun? Zitieren
Klotzkopp Geschrieben 9. Dezember 2002 Geschrieben 9. Dezember 2002 Originally posted by Guybrush Threepwood was stimmt denn nun? Das ist eigentlich egal, weil die Werte intern miteinander multipliziert werden. Der eine Wert gibt die Anzahl der Datenelemente an, der andere die Größe eines Datenelements. Du schreibst also gerade für jedes gelesene Byte einen 1000-Byte-Array in Deine Datei. Schreib mal statt sizeof© sizeof(*c). Zitieren
Guybrush Threepwood Geschrieben 9. Dezember 2002 Autor Geschrieben 9. Dezember 2002 Schreib mal statt sizeof© sizeof(*c). Bei beidem kommt der selbe Fehler. Zitieren
Klotzkopp Geschrieben 9. Dezember 2002 Geschrieben 9. Dezember 2002 Originally posted by Guybrush Threepwood Bei beidem kommt der selbe Fehler. Eigenartig. Was steht denn zu dem Zeitpunkt in dwRead? Zitieren
Guybrush Threepwood Geschrieben 9. Dezember 2002 Autor Geschrieben 9. Dezember 2002 592, er ist aber noch nicht am Ende der Datei, weil er hat bis dahin ca 4307000 Zeichen gelesen und die Datei ist ca. 6MB Groß. Zitieren
Guybrush Threepwood Geschrieben 9. Dezember 2002 Autor Geschrieben 9. Dezember 2002 Ich hab das Problem jetzt etwas umständlicher gelöst, aber Hauptsache es klappt. Hier ist die Schleife: while(dwRead != NULL) //Status = Null wenn InternetReadFile am Ende der Datei { if (InternetReadFile(hFile,c,1000,&dwRead) == FALSE) //1 Zeichen aus der Quelldatei lesen { Fehler("Von der Quelldatei konnte nicht gelesen werden.",GetLastError()); SendMessage(hMainWindow,WM_CLOSE,0,0); } if (dwRead != NULL) { //putc(c,stream); //Das Zeichen in die Zieldatei schreiben for (int z=0; z<dwRead; z++) { fputc(c[z],stream); i++; //Zähler erhöhen if (i % o == 0) //Wenn 1/100 geschrieben { SendMessage(hProgress,PBM_STEPIT,0,0); //Progressbar um einen Schritt weiter } } } } [/PHP] Gruß Guybrush Zitieren
Guybrush Threepwood Geschrieben 7. Oktober 2003 Autor Geschrieben 7. Oktober 2003 Hat irgendwer noch ein paar Tipps wie man den Downloadvorgang beschleunigen könnte? Wenn ich mit dem Programm eine 20MB Datei runterlade dauert das ca 4,5 Minuten, mit dem IE dauerts nur 1,5-2 Minuten. while(dwRead != NULL) { if (InternetReadFile(hRequest,c,1000,&dwRead) == FALSE) { Fehler("Von der Quelldatei konnte nicht gelesen werden.",GetLastError()); SendMessage(hMainWindow,WM_DESTROY,0,0); return -1; } if (dwRead != NULL) { if (WriteFile(hFile,c,dwRead,&dwWrite,0) == NULL) { sprintf(szMeldung,"Beim schreiben in die Datei\n%s\ntrat ein Fehler auf.",szDatei); Fehler(szMeldung,GetLastError()); SendMessage(hMainWindow,WM_DESTROY,0,0); return -1; } else { i+=dwWrite; //Zähler erhöhen nKopZeichen+=dwWrite; if (i >= o) //Wenn 1/100 geschrieben { //Unwichtiger Code um Progress Bar zu aktualiesieren } } } } [/PHP] Gibt es vielleicht ein Möglichkeit zu errechnen wieviele Zeichen optimal gelesen werden? Also anstatt 1000 Zeichen 3567 oder so. Zitieren
Goos Geschrieben 7. Oktober 2003 Geschrieben 7. Oktober 2003 Original geschrieben von Guybrush Threepwood Es gibt zwar funktionendie die Datei komplett und schneller kopieren würden, aber dann hätte ich ja nicht die Progressbar die anzeigt wie weit man ist. Was zeigt deine Progressbar denn genau an (nur Fortschritt oder auch Zeit?) und wie wichtig ist die und wie genau muss sie anzeigen? Goos Zitieren
Guybrush Threepwood Geschrieben 7. Oktober 2003 Autor Geschrieben 7. Oktober 2003 Jetzt kram doch hier nicht meine alten Aussagen raus:D Die zeigt den Fortschritt der aktuellen Datei und den Gesamtfortschritt an. Was ich aber auch benötige ist, dass man einen abgebrochenen Download fortzusetzen kann und das geht (soweit ich weiß) nur wenn ich es selber mache. Zitieren
Klotzkopp Geschrieben 7. Oktober 2003 Geschrieben 7. Oktober 2003 Ich würde die Größe des Datenblocks variabel machen. Setz dir eine Unter- und eine Obergrenze, und nimm dazwischen einen bestimmten Anteil der Dateigröße (z.B. 1%). 1000 Byte sollte eher die Untergrenze sein. Es bringt jedenfalls nichts, wenn du bei einer 20-MByte-Datei 20.000mal dein ProgressBar aktualisierst. Zitieren
Guybrush Threepwood Geschrieben 7. Oktober 2003 Autor Geschrieben 7. Oktober 2003 Hmm das ist ne gute Idee, ich probiers mal aus. Der Fortschrittsbalken wird aber pro Datei nur 100 mal aktualisiert, weil das mit i >= o (wobei o 1/100 der Datei ist) überprüft wird. Zitieren
Goos Geschrieben 7. Oktober 2003 Geschrieben 7. Oktober 2003 Original geschrieben von Guybrush Threepwood Jetzt kram doch hier nicht meine alten Aussagen raus:D Tu ich gar nicht...ich bin nur nicht ganz so schnell im Antworten Original geschrieben von Guybrush Threepwood Die zeigt den Fortschritt der aktuellen Datei und den Gesamtfortschritt an. Dafuer braeuchte es ja nicht megagenau sein und du koenntest auch die von dir erwaehnten schnelleren funktionen nehmen und dann bei deiner Anzeige einfach etwas tricksen. Original geschrieben von Guybrush Threepwood Was ich aber auch benötige ist, dass man einen abgebrochenen Download fortzusetzen kann und das geht (soweit ich weiß) nur wenn ich es selber mache. Das geht dann aber wohl nicht, da wuerd ich dir zustimmen Goos Zitieren
Guybrush Threepwood Geschrieben 7. Oktober 2003 Autor Geschrieben 7. Oktober 2003 @Klotzkopp Du bist einfach genial, ich hab es jetzt auf 1% und im Bereich zwischen 1500-15000 gemacht und es ist genau so schnell wie der IE :e@sy Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.