Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Internet (https://www.clubdelphi.com/foros/forumdisplay.php?f=3)
-   -   Descargar fichero 25 Mb desde internet (https://www.clubdelphi.com/foros/showthread.php?t=45434)

fmatias 03-07-2007 10:21:38

Descargar fichero 25 Mb desde internet
 
Hola a todos,
Quiero crear una aplicación que descargue un fichero desde internet similar a la descarga desde cualquier navegador. Con la siguiente función que os indico realiza el proceso, pero va muy lento y se queda colgado cuando lleva un 10% aprox.
Respecto a la velocidad, he realizado varias pruebas desde distintos navegadores y todos van hasta 10 veces más rápido.

Podríais ayudarme a depurarlo mejor?
Código Delphi [-]
function TForm1.Bajar(Url: string; Archivo: string): Boolean;
var
  hFile: THandle;
  hNet: HINTERNET;
  hUrl: HINTERNET;
  Buffer: array[0..10240] of Char;
  BytesRead: DWORD;
  BytesWritten: DWORD;
begin
  Result := FALSE;
  hFile := CreateFile(PChar(Archivo), GENERIC_WRITE, 0, nil, CREATE_ALWAYS,
    FILE_ATTRIBUTE_NORMAL, 0);
  if (hFile <> INVALID_HANDLE_VALUE) then
  begin
    hNet := InternetOpen('agent', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
    if (hNet <> nil) then
    begin
      hUrl := InternetOpenUrl(hNet, PChar(Url), nil, 0,
        INTERNET_FLAG_RELOAD, 0);
      if (hUrl <> nil) then
      begin
        while (InternetReadFile(hUrl, @Buffer, sizeof(Buffer), BytesRead)) do
        begin
          // Añadir la siguiente liena si es necesario
           Application.ProcessMessages;
          if (BytesRead = 0) then
          begin
            Result := TRUE;
            break;
          end;
          if (not WriteFile(hFile, Buffer, BytesRead, BytesWritten, nil)) then
            break;
          if (BytesRead <> BytesWritten) then
            break;
        end;
        InternetCloseHandle(hUrl);
      end;
      InternetCloseHandle(hNet);
    end;
    CloseHandle(hFile);
  end;
end;
Muchas gracias
F.Matías.

phrodo 03-07-2007 10:49:10

¿por que no pruebas con el componente IDHttp de las Indy?

Es muy facil con ese componente bajar cualquier fichero desde tu propia aplicación

Este codigo lo utilizo yo en una aplicación mia. Espero que te sirva. Yo lo importé de un colega del foro, y funcionó a la perfección. La direccion URL de descarga la tienes que cambiar por la direccion del fichero que quieras descargar.

Código Delphi [-]

 resourcestring

  rsFinDescarga = 'Fin de la descarga';
  rsProgresoDes = 'Progreso descarga %d / %d KB';
  rsUrlDescarga = 'http://www.tudireccion.com/tuarchivo.rar';

procedure TFPpal.btnDescargaClick(Sender: TObject);
begin
  btnDescarga.Enabled := false;
  try
    IdHTTP.Get(rsUrlDescarga);
  finally
    btnDescarga.Enabled := true;
  end;
  ShowMessage(rsFinDescarga);
end;

procedure TfrmPrincipal.IdHTTPWorkBegin(Sender: TObject;
 AWorkMode: TWorkMode; const AWorkCountMax: Integer);
begin
  FTotalBytes := AWorkCountMax;
  bProgreso.Max := AWorkCountMax;
  gProgreso.MaxValue := AWorkCountMax;
end;

procedure TfrmPrincipal.IdHTTPWork(Sender: TObject;
 AWorkMode: TWorkMode; const AWorkCount: Integer);
begin
  Application.ProcessMessages();
  gProgreso.Progress := AWorkCount;
  bProgreso.Position := AWorkCount;

  lbProgresoDescarga.Caption := Format
   (rsProgresoDes, [AWorkCount div 1024,
    FTotalBytes div 1024]);
end;

procedure TfrmPrincipal.IdHTTPWorkEnd(Sender: TObject;
 AWorkMode: TWorkMode);
begin
  gProgreso.Progress := 0;
  bProgreso.Position := 0;

  lbProgresoDescarga.Caption :=
   Format(rsProgresoDes, [0,0]);
end;


espero que te sirva. Un saludo.

fmatias 03-07-2007 11:54:23

Muchas graciasphrodopor contestar tan rápido.

acabo de trabajar con el script que me has enviado y realiza el proceso de descarga correctamente y a buena velocidad.

El problema que detecté al leer el código y una vez probado es que no sé donde guarda el fichero descargado.

He realizado una busqueda en todod el disco y no aparece.

¿Falta aún procedimiento? No he trabajado nunca con las Indys y realmente no sé como funcionan los componentes.

Gracias nuevamente.

fmatias 03-07-2007 12:55:14

Resuelto
 
Bueno, ya he corregido el procedimiento para que se guarde el fichero en local en la dirección indicada.

El procedimiento que me indicó prhodo fue el siguiente:
Código Delphi [-]
procedure TFPpal.btnDescargaClick(Sender: TObject);
begin
  btnDescarga.Enabled := false;
  try
    IdHTTP.Get(rsUrlDescarga);
  finally
    btnDescarga.Enabled := true;
  end;
  ShowMessage(rsFinDescarga);
end;

Para que guarde el fichero lo he modificado de la siguiente forma, añadiendo la variable Destino y modificando la función IdHttp.get

Código Delphi [-]
procedure TForm1.btndescargaClick(Sender: TObject);
var
Destino: TFileStream;
begin
  btnDescarga.Enabled := false;
  Destino:=TFileStream.Create('c:\destino.zip', fmCreate);

  try
    IdHTTP.Get(ecarga.Text,destino);
  finally
    btnDescarga.Enabled := true;
    destino.free;
  end;
  ShowMessage(rsFinDescarga);

end;

Muchas gracias a prhodo por su colaboración, me ha ahorrado bastante tiempo de trabajo.

Saludos a todos.

phrodo 06-07-2007 17:43:59

De nada hombre... es la primera vez que ayudo a alguien del foro (creo)... y la verdad es que sienta muy bien ;)

Está muy bien la solución que le has incorporado. Si me permites proponerte na solución más elegante, sería abrir una ventana de destino (de las que hay en la pestaña "dialogs" de delphi, para que el usuario elija donde desea guardar el archivo.

Luego simplemente le pasas el destino que haya escogido, al FileStream.

un saludo,


La franja horaria es GMT +2. Ahora son las 12:19:56.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi