Search code examples
delphidelphi-2010

Check if jpg url exists before downloading (to prevent an exception)


How can i check to see if a JPG url exists before downloading it, to avoid an exception?

procedure TForm1.Button1Click(Sender: TObject);
var
  FS: TFileStream;
  Url, FileName: String;
  I, C: Integer;
begin
  for I := 1 to 1000 do
  begin
    Url := 'http://www.mysite.com/images/' + IntToSTr(I) + '/Image.jpg';
    FileName := 'C:\Images\' + IntToStr(I) + '.jpg';
    FS := TFileStream.Create(FileName, fmCreate);
    try
      try
        IdHTTP1.Get(Url);
        c := IdHTTP1.ResponseCode;
        if C = 200  then
          IdHTTP1.Get(Url, FS);
      except
      end;
      Application.ProcessMessages;
    finally
      Fs.Free;
    end;
  end;
end;

Solution

  • To answer your main question, the only way you have to check if a particular URL is valid or not is to check against the web server and check what the server tells you.

    With indy you can use the AIgnoreReplies parameter of the Get and other methods to instruct the TIdHTTP instance not to raise an exception in case that status is returned by the web server, like this:

    IdHTTP1.Get(Url, FS, [404]);
    

    A exception will still be raised in case any status different than 200 and 400. There are other status codes that may don't raise an exception depending on various configurations of the component, for example status code 401 and authentication parameters, and others.

    That said, I find several problems in your code:

    • The try/except block you have kills any exception, any exception regardless of what nature the exception may be. It treats the same a EOutOfMemory than a EIdSocketError, EIdHTTPProtocolException or even a EMayanWorldEnd exception!
    • You download the image twice... it happens you just ignore the first downloaded data and use it to try to determine if the resource exists or not. If you feel you must have to check if the resource exists or not, don't perform a GET command over it, perform a HEAD one!
    • Don't use Application.ProcessMessages, move your code to a Thread!
    • Learn to handle in a proper way the different status codes you may get and other errors you may find. It is hard at the beginning, but is the way to go if you want to make it robust. Different errors may be:
      • HTTP status codes, like:
        • Request TimeOut (slow down and retry)
        • HTTP Version Not Supported (well, try with another version)
        • Etc.
      • Network Failures
        • Is the internet down
        • Is the WebServer down
        • Etc.
      • As a general rule, let fly any other exception you don't know how to handle... or if you have no choice, eat them but log what's happening and read the logs, that way you will improve your knowledge and skills.