Zum Inhalt springen

Empfohlene Beiträge

Geschrieben

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

Geschrieben
Originally posted by Guybrush Threepwood

Ich dachte das das vielleicht daran

liegt das immer nur ein Zeichen gelesen wird

Daran 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.
Geschrieben

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]

Geschrieben
Originally posted by Guybrush Threepwood

if (InternetReadFile(hFile,&c,1000,&dwRead) == FALSE) //1 Zeichen aus der Quelldatei lesen

Ist 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.
Geschrieben

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)....".

Geschrieben

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?

Geschrieben
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).
Geschrieben

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]

:D

Gruß

Guybrush

  • 9 Monate später...
Geschrieben

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.

Geschrieben
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

Geschrieben

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.

Geschrieben
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

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.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...