0

by Follow up to my previous question about update listview inside thread here

i start to think in different way to get my previous question solved , because of download process takes too long and takes much bandwidth i want to download GIFimage then save it on disk then use it later inside my application this is current download thread code

procedure TDownloadImage.Execute;
var
  aMs: TMemoryStream;
  aIdHttp: TIdHttp;
begin
  FGif := TGifImage.Create;
  try
    aMs := TMemoryStream.Create;
    try
      aIdHttp := TIdHttp.Create(nil);
      try
        aIdHttp.Request.UserAgent := 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0';
        aIdHttp.Get(FURL, aMs); // here is the client FURL
      finally
        aIdHttp.Free;
      end;
      aMs.Position := 0;
      FGif.LoadFromStream(aMs);
      FGif.Transparent := True;
    finally
      aMs.Free;
    end;
    if Assigned(FOnImageReady) then
      Synchronize(DoImageReady);
    end;
  finally
    FGif.Free;
  end;
end;

i want to save image of FURL on computer client then if this image requested to be download again abort download process and load it from client computer how possibly i can do that ?

Community
  • 1
  • 1
MartinLoanel
  • 184
  • 3
  • 17
  • Use `TFileStream` instead of `TMemoryStream`. – TLama Sep 09 '15 at 14:23
  • yes i know how to load image from disk but the main question about how to save them then if this download matched to that image again don't download but load from disk instead you know to save bandwidth and forget to mention its not 1 image only its possibly will be 100 images consider on how many clients it will be on this application – MartinLoanel Sep 09 '15 at 14:25
  • So you're not asking how to download image to file but how to save it to a file keeping its URI origin ? If so, then you're looking for some sort of cache like browsers have. Browsers store downloaded files in cache folders and references to them with the origin URI in database. Isn't that what you're looking for ? It's about storing `URI=LocalFilePath` pairs. – TLama Sep 09 '15 at 14:33
  • yes its like cache image and don't download it again to make the process fast and save bandwidth – MartinLoanel Sep 09 '15 at 14:37
  • 1
    The purpose is clear now. Well, that opens many ways to go. You can e.g. create a simple name value pair file (or make it more complex, e.g. to create expiration mechanism), use a database (which can store only references, or the files themselves), you can use ready made WinINet caching feature (and we could go deeper). That's still too broad to give a definitive answer. – TLama Sep 09 '15 at 14:55
  • 1
    This is really nothing to do with downloading files and Indy. That bit you can do. Your question is about maintaining a cache. What aspect of that are you struggling with? – David Heffernan Sep 09 '15 at 15:13
  • You could switch to the WinInet `UrlDownloadToFile()` function and let it handle the downloading and caching for you. – Remy Lebeau Sep 09 '15 at 18:09
  • i will try `wininet` suggestion – MartinLoanel Sep 09 '15 at 20:17

1 Answers1

0

As TLama Said wisely, you are looking for a Full Cache mechanism. In Delphi you may want to call it TDictionary.

If you want to save your Gif and URI in memory, then you can use a TDictionary pair, to hold each memory stream and uri, and everything will work fast.

If you want to store the data on files, and each time the application starts to remember the state of previous run, you may want to find a way to store the data, a database, or text file.

If you want a simple text file that can help, an Ini file can do the job, however, as text file grow, then tend to get slow, and make the search slower, then the file fetch.

If you work with a good portable database , maybe the search will be fast.

example code with Ini file to get you started: pseudo code.

var 
  filename:string;//where is the key value is stored.
  GifLocation:string;//result of the cache hit.
const
  URI = 'http://sstatic.net/stackexchange/img/logos/so/so-logo-med.png?v=a4a65015804e';
begin
  with TIniFile.create(filename) do
  try
    GifLocation := readString('FilesLocation',URI,'');
  finally
    free;
  end;
  if ('' = GifLocation) then 
    fetchBoy(URI)
  else IGotIt_IGotIt(GifLocation);
end;

Implement your fetchBoy, for doing an http get, and IGotIt_IGotIt to load file stream.

none
  • 4,669
  • 14
  • 62
  • 102