2010-08-17 24 views
11

Una búsqueda en Google muestra algunos ejemplos sobre cómo descargar un archivo en Delphi, pero la mayoría tienen errores y la mitad de las veces no funcionan en mi experiencia.Descarga de un archivo en Delphi

Estoy buscando una solución simple y robusta que me permita descargar un solo exe (para actualizar mi aplicación) y contendrá la ejecución del hilo de actualización actual hasta que la descarga finalice o se produzcan errores. El proceso ya está enhebrado, por lo que el código de descarga debe mantener la ejecución hasta que finalice (con suerte).

Aquí hay dos implementaciones, ambos parecen muy complicado
1. http://www.scalabium.com/faq/dct0116.htm
2. http://delphi.about.com/od/internetintranet/a/get_file_net.htm

Respuesta

12

El segundo enfoque es la forma estándar de la utilización de los recursos de Internet utilizando WinINet, una parte de la API de Windows. Lo he usado mucho, y siempre ha funcionado bien. El primer enfoque que nunca he intentado. (Ninguno es "muy complicado". Siempre habrá algunos pasos adicionales al usar la API de Windows.)

Si desea un método muy simple, simplemente puede llamar al UrlMon.URLDownloadToFile. No obtendrá ningún control preciso (¡en absoluto!) Sobre la descarga, pero es muy simple.

Ejemplo:

URLDownloadToFile(nil, 
        'http://www.rejbrand.se', 
        PChar(ExtractFilePath(Application.ExeName) + 'download.htm'), 
        0, 
        nil); 
+3

Sugerencia: reemplace 'Application.ExeName' con' ParamStr (0) 'para eliminar la dependencia de la unidad' Forms'. – mjn

+0

@mjustin: cierto. Pero en el código de producción, no querrá guardar archivos en el directorio de la aplicación de todos modos, que es de solo lectura (Archivos de programa), a menos que el programa sea portátil (se ejecuta en una memoria USB, por ejemplo). –

+0

Gracias por la respuesta Andreas. Fui con el segundo enfoque que publiqué ya que dijiste que era el estándar, con suerte resulta ser confiable. Gracias por tu esfuerzo. – Daisetsu

16

por qué no hacer uso de Indy. Si se utiliza el TIdHTTP su simple

procedure DownloadFile;  
var 
    IdHTTP1: TIdHTTP; 
    Stream: TMemoryStream; 
    Url, FileName: String; 
begin  
    Url := 'http://www.rejbrand.se'; 
    Filename := 'download.htm'; 

    IdHTTP1 := TIdHTTP.Create(Self); 
    Stream := TMemoryStream.Create; 
    try 
    IdHTTP1.Get(Url, Stream); 
    Stream.SaveToFile(FileName); 
    finally 
    Stream.Free; 
    IdHTTP1.Free; 
    end; 
end; 

Usted puede incluso agregar una barra de progreso con la OnWork y OnWorkBegin Eventos

procedure IdHTTPWorkBegin(ASender: TObject; AWorkMode: TWorkMode;AWorkCountMax: Int64); 
begin 
    ProgressBar.Max := AWorkCountMax; 
    ProgressBar.Position := 0; 
end; 

procedure IdHTTPWork(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64); 
begin 
    ProgressBar.Position := AWorkCount; 
end; 

No estoy seguro de si estos incendios evento en el contexto de los principales hilo, por lo que las actualizaciones realizadas a los componentes VCL pueden tener que hacerse utilizando el componente tidnotify para aviod threading issues. Tal vez alguien más pueda verificar eso.

+1

Si el archivo es grande, es posible que desee utilizar una secuencia de archivos en lugar de una secuencia de memoria. – MikeT

Cuestiones relacionadas