Witam.
Poniżej standardowa procedura do ściągania pliku, która chciałbym usprawnić,
mam nadzieję że nie przestarzała, ale u mnie się na razie sprawdza.
Szukam informacji na temat jak ograniczyć prędkość ściągania a konkretnie idealne było by:
- Jak sprawdzić prędkość pobierania z danego stanowiska np. SpeedNet=?B.
- Jak zabezpieczyć się przed zawieszeniem w trakcje pobierania danych gdy internet padnie.
- Na koniec jak ściągnąć plik z prędkością +-SpeedNet/10 B/s?
Zastanawiałem się nad wątkami, ale manewrowanie priorytetami wątków nie jest na tyle precyzyjne,
no i oczywiście jeśli dany wątek ściągający plik wisi to trzeba go umiejętnie kontrolować,
a ja chciałem rozwiązać problem w zarodku ... o ile się da.
//Procedura ściąga lub "dociąga" plik z internetu...
function TNetFtp.SciagnijFile(Sender: TObject; adresURL, FNameZapisu :String): Boolean;
// adresURL - zmienna z adresem URL z którego ściągamy plik
// nazwaPliku - {nazwa pliku jaka ma być po ściągnięciu, może być dowolna
var
plik :File;
inOpen, inURL :HINTERNET;
HTTPRozmiarPliku, HTTPRozmiarPliku1 :DWORD;
ileZnakow :DWord;
dwBufLen, dwIndex :DWord;
Sciagnieto, HDRozmiarPliku :DWord;
bufor :array[1..1024] of byte;
buf :Pointer;
begin
Result:= False;
Stop:= false;
//ustawiamy dane...
inOpen:= nil;
inURL:= nil;
HDRozmiarPliku:= 0;
HTTPRozmiarPliku:= 0;
Sciagnieto:= 0;
// ProgressBar1.Position:= 0;
// jesli plik o takie j nazwie nie jest dostępny
if ExistURL(adresURL) = False then begin Result:= False; Exit; end;
//pobieramy rozmiar pliku jeżeli coś już ściągaliśmy...
if FileExists(FNameZapisu) then
begin
AssignFile(plik, FNameZapisu);
Reset(plik, 1);
HDRozmiarPliku:= FileSize(plik); //pobieramy rozmiar pliku
Seek(plik, FileSize(plik)); //ustawiamy skażnik na końcu pliku
end
else
begin
AssignFile(plik,FNameZapisu);
ReWrite(plik, 1);
end;
Try
//łączymy się z serwerem...
//Label1.Caption:='Łączenie...'; // ------------------------------------
//Application.ProcessMessages;
inOpen:= InternetOpen('Mozilla', PRE_CONFIG_INTERNET_ACCESS, nil, nil, 0);
inURL:= InternetOpenURL
(inOpen, PChar(adresURL), 'Accept: */*', StrLen('Accept: */*'),0 ,0 );
if not (inURL <> nil) then
begin
// ShowMessage('Nie można uzyskać połączenia'); // -------------------
Stop:= True;
InternetCloseHandle(inURL);
InternetCloseHandle(inOpen);
CloseFile(plik);
Exit;
end;
//pobieramy całkowity rozmiar pliku znajdującego sie na serwerze...
dwIndex:= 0;
dwBufLen:= 1024;
GetMem(Buf, dwBufLen);
HttpQueryInfo(inURL, HTTP_QUERY_CONTENT_LENGTH, buf, dwBufLen, dwIndex);
//ustawiamy progresy (paski postępu)
HTTPRozmiarPliku1:= StrToInt(StrPas(Buf));
HTTPRozmiarPliku := HTTPRozmiarPliku1;
//Caption:= 'Rozmiar pliku do ściągnięcia: '+ IntToStr(rozmiar);
// ProgressBar1.Max:= rozmiar;
// ProgressBar1.Position:= rozmiarPliku;
{ ustawiamy wskażnik pliku znajdującego się na serwerze, czyli
ustalamy od jakiego miejsca w pliku rozpoczynamy pobieranie }
if HDRozmiarPliku > 0
then InternetSetFilePointer(inURL, HDRozmiarPliku, nil, 0, 0);
//pobieranie pliku z serwera...
//Label1.Caption:='Ściąganie pliku...'; // -------------------------------
while (ileZnakow <> 0) and (Stop = false) do
begin
InternetReadFile(inURL, @bufor, SizeOf (bufor), ileZnakow);
InternetQueryDataAvailable(inURL, HTTPRozmiarPliku, 0, 0);
BlockWrite(plik, bufor, ileZnakow);
Sciagnieto:= FileSize(plik);
// Label2.Caption:='Ściągnięto '+ IntToStr(sciagnieto); // ------------
// ProgressBar1.Position:= sciagnieto;
// Application.ProcessMessages;
end;
except
//ShowMessage('Wystąpił błąd podczas ściągania pliku !');
Stop:= True;
InternetCloseHandle(inURL);
InternetCloseHandle(inOpen);
CloseFile(plik);
Exit;
end;
Stop:= False;
InternetCloseHandle(inURL);
InternetCloseHandle(inOpen);
CloseFile(plik);
if (HDRozmiarPliku = HTTPRozmiarPliku1) or (Sciagnieto = HTTPRozmiarPliku1)
then Result:= True
else Result:= False;
{
if ProgressBar1.Position = ProgressBar1.Max then
// Label1.Caption:= 'Plik został ściągnięty' // -----------------------
else Label1.Caption:= 'Zatrzymane ściąganie pliku';
}
//Beep;
end;