Get file name from URI string in C#

212,612

Solution 1

You can just make a System.Uri object, and use IsFile to verify it's a file, then Uri.LocalPath to extract the filename.

This is much safer, as it provides you a means to check the validity of the URI as well.


Edit in response to comment:

To get just the full filename, I'd use:

Uri uri = new Uri(hreflink);
if (uri.IsFile) {
    string filename = System.IO.Path.GetFileName(uri.LocalPath);
}

This does all of the error checking for you, and is platform-neutral. All of the special cases get handled for you quickly and easily.

Solution 2

Uri.IsFile doesn't work with http urls. It only works for "file://". From MSDN : "The IsFile property is true when the Scheme property equals UriSchemeFile." So you can't depend on that.

Uri uri = new Uri(hreflink);
string filename = System.IO.Path.GetFileName(uri.LocalPath);

Solution 3

Most other answers are either incomplete or don't deal with stuff coming after the path (query string/hash).

readonly static Uri SomeBaseUri = new Uri("http://canbeanything");
static string GetFileNameFromUrl(string url)
{
    Uri uri;
    if (!Uri.TryCreate(url, UriKind.Absolute, out uri))
        uri = new Uri(SomeBaseUri, url);
    return Path.GetFileName(uri.LocalPath);
}

Test results:

GetFileNameFromUrl("");                                         // ""
GetFileNameFromUrl("test");                                     // "test"
GetFileNameFromUrl("test.xml");                                 // "test.xml"
GetFileNameFromUrl("/test.xml");                                // "test.xml"
GetFileNameFromUrl("/test.xml?q=1");                            // "test.xml"
GetFileNameFromUrl("/test.xml?q=1&x=3");                        // "test.xml"
GetFileNameFromUrl("test.xml?q=1&x=3");                         // "test.xml"
GetFileNameFromUrl("http://www.a.com/test.xml?q=1&x=3");        // "test.xml"
GetFileNameFromUrl("http://www.a.com/test.xml?q=1&x=3#aidjsf"); // "test.xml"
GetFileNameFromUrl("http://www.a.com/a/b/c/d");                 // "d"
GetFileNameFromUrl("http://www.a.com/a/b/c/d/e/");              // ""

Solution 4

The accepted answer is problematic for http urls. Moreover Uri.LocalPath does Windows specific conversions, and as someone pointed out leaves query strings in there. A better way is to use Uri.AbsolutePath

The correct way to do this for http urls is:

Uri uri = new Uri(hreflink);
string filename = System.IO.Path.GetFileName(uri.AbsolutePath);

Solution 5

I think this will do what you need:

var uri = new Uri(hreflink);
var filename = uri.Segments.Last();
Share:
212,612

Related videos on Youtube

paulwhit
Author by

paulwhit

I'm a software developer, a super geek, and a traveler. I'm passionate about people, technology and writing. I live in Washington, DC with my two kitties.

Updated on December 09, 2020

Comments

  • paulwhit
    paulwhit about 2 years

    I have this method for grabbing the file name from a string URI. What can I do to make it more robust?

    private string GetFileName(string hrefLink)
    {
        string[] parts = hrefLink.Split('/');
        string fileName = "";
        if (parts.Length > 0)
            fileName = parts[parts.Length - 1];
        else
            fileName = hrefLink;
        return fileName;
    }
    
  • Fear605 over 13 years
    Colons are not acceptable in paths on all platforms, so this sort of hack might fail on, say, Mono.NET running on a *nix variant. Better to use System.Uri since it is specifically designed to do what the OP needs.
  • Doctor Jones
    Doctor Jones over 13 years
    I agree, you should really use the Uri class as it already does this stuff for you. +1
  • STW
    STW over 13 years
    Yup, as simple as it may seem to roll-your-own the Uri class has lots of pre-rolled parsing/validating/encoding goodies in it for you.
  • Reed Copsey
    Reed Copsey over 13 years
    @paulwhit: In that case, you should use Path.GetFileName on the results of Uri.LocalPath. This is a completely safe, highly checked way of handling it. I will edit my answer to include this. See: msdn.microsoft.com/en-us/library/…
  • user3827001
    user3827001 over 13 years
    Works great for absolute Urls, doesn't work for relative though. The Uri class is very limited when working with relative urls.
  • masiboo
    masiboo over 11 years
    How to do int in wp7, looks like Path.GetFileName is not available. Can anybody advice how to do it?
  • dethSwatch
    dethSwatch about 11 years
    isFile appears to only look at the scheme. So: "www/myFile.jpg" returns false, "file://www/something.jpg" returns true, so it's useless in this case.
  • Reed Copsey
    Reed Copsey over 10 years
    @RAJ... I'd just put in a new question
  • Kam Figy over 9 years
    Worth noting that a Uri can contain characters, such as " and <, that cannot be on filesystem paths. The Path class checks for these invalid characters and will throw an exception if they exist. Using Uri.LocalPath does not remove these characters. I wrote up a post on the issue
  • Julian
    Julian almost 8 years
    Also beware of a querystring. http://www.test.com/file1.txt?a=b will result in file1.txt?a=b
  • David
    David over 7 years
    Didn't work for http://url/start.aspx#/_catalogs/masterpage/my.master, I'm now using: filename = System.IO.Path.GetFileName(strMasterPageURL.Split('/').Last(‌​));
  • Kostub Deshmukh
    Kostub Deshmukh almost 7 years
    Uri.LocalPath does Windows specific conversions and does not work correctly in a non-Windows environment. See my answer below for a portable way to do this.
  • Jahmic
    Jahmic about 6 years
    Also, Path.GetFullPath didn't work for "file://localhost/C:/Users/username/path/to/". I had to add 'path = uri.LocalPath.Replace("\\\\localhost\\", "");'. Not quite as elegant.
  • andrew pate
    andrew pate over 5 years
    Note: This gives just the filename (as the question asks) NOT a full path... If you are after that try: System.IO.Path.GetFullPath(uri.AbsolutePath);
  • Jeff Moser
    Jeff Moser over 5 years
    Note that for escaped URLs like http://example.com/dir/hello%20world.txt this would return hello%20world.txt whereas the Uri.LocalPath approach would return hello world.txt
  • ckittel
    ckittel about 4 years
    Why would GetFileNameFromUrl("test") result in "test.xml" Or is that just a typo?
  • Alex Pandrea
    Alex Pandrea almost 4 years
    While you can't use Uri.IsFile to test on a http URL/scheme, you can successfully extract the file name from a http URL using System.IO.Path.GetFileName(url);
  • Ronald
    Ronald almost 4 years
    This looks like an elegant solution indeed, but just keep in mind this only works on absolute URIs and returns an encoded/escaped value (use Uri.UnescapeDataString() to change %20 and + to spaces).
  • Alexandre Daubricourt
    Alexandre Daubricourt about 2 years
    Does not work as of .NET Core 3.0 (query string is not removed from path)
  • MsBao about 2 years
    @AlexandreDaubricourt I just tested on netcore 3.0, 3.1 and on net5.0 (all on windows) and the output was correct w/ no changes. Is the code failing on a different OS under netcore 3.0?