Zum Inhalt springen
View in the app

A better way to browse. Learn more.

Fachinformatiker.de

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Empfohlene Antworten

Veröffentlicht

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

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.
  • Autor

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]

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.
  • Autor

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

  • Autor

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?

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).
  • Autor

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...
  • Autor

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.

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

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.

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

Erstelle ein Konto oder melde dich an, um einen Kommentar zu schreiben.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.