Page 2 of 2 FirstFirst 1 2
Results 16 to 18 of 18

Thread: download bestanden via http en listbox

  1. #16
    John Kuiper
    Join Date
    Apr 2007
    Location
    Almere
    Posts
    8,747
    Een klein stukje van de sluier dan
    Code:
    var MemoryStream:TMemoryStream;
    begin
      MemoryStream:=TMemoryStream.Create;
      try
        IdHTTP1.get('http://www.mixfreaksparty.nl/index.html',memorystream);
        MemoryStream.Position:=0;
        Memo1.Lines.LoadFromStream(MemoryStream);
      finally
        MemoryStream.Free;
      end;
    end;
    Overigens heb ik het gevonden via Google (zoek op : delphi TidHttp get example).

    Verder heb ik nog nooit met indy gewerkt.
    Delphi is great. Lazarus is more powerfull

  2. #17
    Aangezien je duidelijk nog wat problemen hebt met verschillende basisdingen, zoals het gebruik van een for-lus, en werken met visuele controls (listbox) en niet visuele controls (IdHTTP), en natuurlijk het gebruik van een filestream, is het wel handig om je probleem in meerdere stappen onder te verdelen.

    IdHTTP

    Laten we dus eens kijken naar die IdHTTP.
    TIdHTTP is een component dat een enkel request kan afvuren naar een webserver. Zoals VideoRipper al schreef, is een HTTP request een eenmalige opdracht waar je een antwoord op krijgt. Zowel de vraag (het request) als het antwoord (de response) kunnen ingewikkeld zijn, maar de makkelijkste vorm is simpelweg een url die je een bepaald bestand teruggeeft.

    IdHTTP heeft de method Get. Deze kan de inhoud van het bestand (of eigenlijk: van de respons) teruggeven als string. Je roept deze dan aan in de vorm
    Code:
    StringVariabele := IdHTTP1.Get(Url);
    Deze vorm werkt vooral goed als je een tekstresultaat verwacht, bijvoorbeeld een stuk HTML, dat je wilt weergeven of verder gebruiken in je programma.

    Stream

    Een andere mogelijkheid is om IdHTTP.Get aan te roepen als procedure en een Stream mee te geven die gevuld moet worden. Dat is meteen al een stuk ingewikkelder, omdat je daarvoor in je code een stream object moeten maken én vrijgeven.

    Een stream is een object dat je helpt bij het lezen en schrijven van een bonk data. Die data kan tekst zijn, of binaire data, zoals een plaatje of een zipfile.
    Je hebt verschillende soorten streams, zoals de MemoryStream die de data in het geheugen houdt, of de FileStream die de data in een bestand opslaat of daaruit leest.

    Data downloaden naar een stream gaat zo:
    Code:
    IdHTTP1.Get(Url, StreamObject);
    Deze laatste vorm moet je nu maar gebruiken, omdat je een lijst bestanden wilt downloaden.

    Stap 1: URL downloaden naar stream

    We beginnen met één bestand. Zet een button op je form en schijf in het OnClick event de volgende code.
    Ik neem aan dat je weet hoe je events aan een button moet koppelen. Zo niet, dan moet je deze thread maar even laten rusten en de basis gaan bestuderen.

    Delphi Code:
    1. procedure TForm1.Button1Click(Sender: TObject);
    2. var
    3.   Stream: TFileStream;
    4. begin
    5.   Stream := TFileStream.Create('c:\ff\plaatje.gif', fmCreate);
    6.   try
    7.     IdHTTP1.Get('http://www.mce.k12tn.net/reading45/bulb.gif', Stream);
    8.   finally
    9.     Stream.Free;
    10.   end;
    11. end;
    Deze code laat zien dat er een FileStream object gemaakt wordt dat verwijst naar een bestand. Bij het maken wordt ook fmCreate meegegeven. Dat betekent dat het bestand moet worden gemaakt. Het betekent ook (zie de helpfile) dat het bestand wordt overschreven als het al bestaat!

    Vervolgens wordt de Get method van IdHTTP1 aangeroepen. In dit geval in de vorm die een stream accepteert.
    De hele inhoud die wordt gedownload vanaf de url wordt opgeslagen in de stream. Omdat het een filestream is wordt die data automatisch in die file gezet.

    Als het downloaden klaar is wordt het stream object vrijgegeven. De file wordt afgesloten, maar de data staat er nu wel in.

    try..finally
    Overigens wordt daar try..finally gebruikt. Dat is een constructie die er voor zorgt dat het FileStream object altijd wordt vrijgegeven, ook als er een fout ontstaat bij het downloaden. Een uitgebreide discussie hierover vind je in "werking try finally".

    Goed. Dat is de eerste stap. Je downloadt maar 1 bestand, en zowel de url daarvan als de bestandsnaam zijn in je code hard vastgelegd.

    Stap 2: Functionaliteit isoleren in een functie

    Op zich hebben we al een mooi stukje code, maar het zou handiger zijn om dit wat flexibeler te maken, zodat je het kunt hergebruiken. Daarvoor kun je een losse functie maken. In dit geval wil je wel gebruikmaken van het IdHTTP control op je form, daarom maken we deze functie onderdeel van je form. Het is dan een method. Dat wil zeggen, een functie of procedure die onderdeel is van een object class, in dit geval van de class TForm1.

    Als je inderdaad een nieuw form hebt, dan heb je nog een vrij eenvoudige form-declaratie. Daar kun je een nieuwe method bij maken, zodat je dit krijgt:
    Delphi Code:
    1. type
    2.   TForm1 = class(TForm)
    3.     Button1: TButton;
    4.     IdHTTP1: TIdHTTP;
    5.     procedure Button1Click(Sender: TObject);
    6.   private
    7.     { Private declarations }
    8.   public
    9.     { Public declarations }
    10.     procedure DownloadUrl(Url: string; FileName: string);
    11.   end;
    De procedure DownloadUrl is de declaratie van de nieuwe method. Deze procedure gaat hetzelfde doen als Button1Click in stap1 doet, maar nu niet met een vaste Url en bestandsnaam, maar met parameters.
    Het eenvoudigst is om nu op Ctrl+Shift+C te drukken. Dit is de zgn. Class Completion. Methods die je gedeclareerd hebt worden nu automatisch gemaakt. Je krijgt een lege procedure die er als volgt uit ziet:
    Delphi Code:
    1. procedure TForm1.DownloadUrl(Url, FileName: string);
    2. begin
    3.  
    4. end;
    Nu moet je de hele code van Button1Click daarheen verplaatsen. Vervolgens pas je de vaste Url en bestandsnaam aan, zodat de parameters van de procedure worden gebruikt:
    Delphi Code:
    1. procedure TForm1.DownloadUrl(Url, FileName: string);
    2. var
    3.   Stream: TFileStream;
    4. begin
    5.   Stream := TFileStream.Create(FileName, fmCreate);
    6.   try
    7.     IdHTTP1.Get(Url, Stream);
    8.   finally
    9.     Stream.Free;
    10.   end;
    11. end;
    De code in Button1Click kan nu helemaal weg. Deze kun je vervangen door:
    Delphi Code:
    1. DownloadUrl('http://www.mce.k12tn.net/reading45/bulb.gif', 'c:\ff\plaatje.gif');
    Als je nu je programma uitvoert, dan zie je dat de werking nog steeds hetzelfde is.

    Stap 3: Een lijst bestanden downloaden

    Tja, dan wordt het lastig, want zoals al eerder aangegeven kun je niet bepalen welke bestanden allemaal op de server aanwezig zijn. Natuurlijk kun je wel zelf een lijst van bestanden maken om te downloaden. Die urls kun je allemaal in een listbox zetten. Daarvoor gebruik je de property Items van de listbox. In de Object Inspector kun je die property vinden en aanpassen.

    Zet dus een listbox op je form en zet de url van bulb.gif in de Items property.

    Vervolgens moet je een stukje code schrijven dat alle bestanden in de listbox één voor één gaat downloaden. Daarvoor gebruik je de for-lus.
    De items in de listbox zijn genummerd van 0. Het eerste item is dus 0, het laatste item is count - 1. Daarom zien de meeste for-lussen er zo uit:
    Code:
    for i := 0 to Listbox1.Items.Count - 1 do
    Vervolgens haal je het item op dat als nummer i heeft. Met een klein truukje kun je de bestandsnaam uit de url isoleren. Die bestandsnaam kun je dan gebruiken om het bestand op te slaan. Ik gebruik daarvoor de functie ExtractFileName. Deze neemt alles na de laatste backslash ( \ ). Omdat een Url natuurlijk alleen voorwaartse slashes kent, vervang ik ze in een tijdelijke variabele met backslashes.

    De bestandsnaam wordt vervolgens achter het vaste downloadpad geplakt, zodat de bestanden in de juiste directory worden opgeslagen, onder de bestandsnaam die ze in de Url hebben.

    De code ziet er dan zo uit:
    Delphi Code:
    1. procedure TForm1.Button1Click(Sender: TObject);
    2. var
    3.   i: Integer;
    4.   Url: string;
    5.   SlashFix: string;
    6.   FileName: string;
    7. begin
    8.   for i := 0 to Listbox1.Items.Count - 1 do
    9.   begin
    10.     Url := Listbox1.Items[i];
    11.  
    12.     SlashFix := StringReplace(Url, '/', '\', [rfReplaceAll]);
    13.     FileName := ExtractFileName(SlashFix);
    14.  
    15.     DownloadUrl(Url, 'c:\ff\' + FileName);
    16.   end;
    17. end;
    Eventueel kun je het download pad vragen in een editbox. Op die manier hoeft dat ook niet vast in code te zijn.

    Hoe je die lijst gaat vullen moet je ook maar nader bepalen. Je kunt deze laden uit een tekstbestand, maar je kunt ook een memo gebruiken in plaats van een listbox. Een memo heeft lines in plaats van items, maar werkt verder op dezelfde manier. Alleen kun je in een memo wel typen. Daar kun je dus gewoon de urls in plakken die je wilt downloaden..
    Zet dan wel de property Memo1.WordWrap op False..

    Succes!
    Last edited by GolezTrol; 20-Sep-09 at 13:27.
    1+1=b

  3. #18
    dit is nou nog eens een mooie uitleg harstikke bedankt.

    en ik ga hier mee aan slag

    bedankt allemaal

Page 2 of 2 FirstFirst 1 2

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •