Search code examples
delphiwinapidelphi-2010urlencodeurl-encoding

What's the best way to URLEncode a file name in Delphi?


My desktop application has to download a file from the internet. The path to the file is known, the file name itself is semi variable, i.e. someone else will be putting new files there, and my application will have to download those.

Now I want to make sure that the URL is safe, and that it will be interpreted correctly. Also, if there's a '#' in a file name (you never know), I do want it to be encoded. Javascript has two distinct functions for this: encodeURI and encodeURIComponent. The latter also encodes '#' characters, amongst other things. Of course, I could roll my own, but I figured that there’s bound to be functions ready for that, and I might as well avoid making some old mistake.

I will be downloading the file with a object that uses the WinInet series of API functions (InternetOpen and its ilk).

So I started rummaging around on MSDN, and sure enough, there’s UrlCanonicalize. But there's also UrlEscape, CreateUri (but that’s not present in the Delphi 2010 units), and finally InternetCreateUrl, which requires me to split up the entire URL. I’d rather concatenate the first portion of the URL with the URLEncoded filename.

Also, they all have tons of different flags, different defaults which have changed over the course of the Windows versions, and I can’t figure out the differences anymore. Does anybody know which one is best for this purpose?


Solution

  • try the TIdURI.PathEncode function (located in the idURI unit) which is part of the Indy library included with delphi.

    {$APPTYPE CONSOLE}
    
    {$R *.res}
    
    uses
      idURI,
      SysUtils;
    
    Var
      FileName : string;
      Encoded  : string;
    begin
      try
       FileName:='File with a Very weird f***name*#%*#%<>[]';
       Encoded:=TIdURI.PathEncode(FileName);
       Writeln(Encoded);
      except
        on E: Exception do
          Writeln(E.ClassName, ': ', E.Message);
      end;
      Readln;
    end.
    

    This will return

    File%20with%20a%20Very%20weird%20f%2A%2A%2Aname%2A%23%25%2A%23%25%3C%3E%5B%5D
    

    Also you can take a look in the TIdURI.URLDecode and TIdURI.URLEncode functions.