Get file name from URI string in C#
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();
Related videos on Youtube

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, 2020Comments
-
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 yearsColons 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 over 13 yearsI agree, you should really use the Uri class as it already does this stuff for you. +1
-
STW over 13 yearsYup, 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 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 over 13 yearsWorks great for absolute Urls, doesn't work for relative though. The Uri class is very limited when working with relative urls.
-
masiboo over 11 yearsHow to do int in wp7, looks like Path.GetFileName is not available. Can anybody advice how to do it?
-
dethSwatch about 11 yearsisFile 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 over 10 years@RAJ... I'd just put in a new question
-
Kam Figy over 9 yearsWorth 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 almost 8 yearsAlso beware of a querystring.
http://www.test.com/file1.txt?a=b
will result infile1.txt?a=b
-
David over 7 yearsDidn'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 almost 7 yearsUri.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 about 6 yearsAlso, 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 over 5 yearsNote: 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 over 5 yearsNote that for escaped URLs like
http://example.com/dir/hello%20world.txt
this would returnhello%20world.txt
whereas theUri.LocalPath
approach would returnhello world.txt
-
ckittel about 4 yearsWhy would
GetFileNameFromUrl("test")
result in"test.xml"
Or is that just a typo? -
Alex Pandrea almost 4 yearsWhile you can't use
Uri.IsFile
to test on a http URL/scheme, you can successfully extract the file name from a http URL usingSystem.IO.Path.GetFileName(url);
-
Ronald almost 4 yearsThis 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 about 2 yearsDoes 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?