28
votes

What's the most concise (but safe) way to remove a drive name, network path, etc. from an absolute path in C#?

For example, converting

\\networkmachine\foo\bar

or

C:\foo\bar

to \foo\bar.

There seem to be a good number of questions already answered with regards to path matters, but I couldn't quite find what I was looking for. My own first thought that came to mind was to use Path.GetFullPath() to ensure I'm indeed working with an absolute path and then to just use a regular expression to find the first slash that isn't next to another one. However, using a regular expression to do path manipulation seems slightly dangerous.

Would it perhaps be wiser to get the drive letter/target network machine/etc, convert the strings to Uri, and ask for the path relative to the drive/machine, and then convert back to strings? Or is there an even better approach?

4
I've written my own helper functions that deal with this. Just some if...else and string operations.Uwe Keim
Then it may be nice to share those methods with us. Or else, your comment was useless :)Jan Sverre
You could strip the string returned from Path.GetPathRoot() from the beginning of the path, but that would also strip foo from the network-path, since this is the share-name.DeCaf
Or if you are doing much of these manipulations you may want to check out alphafs.codeplex.com which contains some additional path manipulation options to those provided by .NET along with support for extended paths (also not available in standard .NET)DeCaf

4 Answers

41
votes

use

string MyPath = @""; // \\networkmachine\foo\bar OR C:\foo\bar
string MyPathWithoutDriveOrNetworkShare = MyPath.Substring (Path.GetPathRoot(MyPath).Length);

Result for C:\foo\bar would be foo\bar and for \\networkmachine\foo\bar would be bar.

For MSDN reference see http://msdn.microsoft.com/en-us/library/system.io.path.getpathroot.aspx

EDIT - as per comments:

With "string voodoo" (which is NOT concise IMHO and thus NOT recommended) you could do this:

if ( ( MyPath.IndexOf (":") == 1 ) || ( MyPath.IndexOf ( "\\\\" ) == 0 ) )
     { MyPathWithoutDriveOrNetworkShare = MyPath.Substring (2); }
if ( MyPathWithoutDriveOrNetworkShare.IndexOf ( "\\" ) > 0 )
     MyPathWithoutDriveOrNetworkShare = MyPathWithoutDriveOrNetworkShare.Substring ( MyPathWithoutDriveOrNetworkShare.IndexOf ( "\\" ) );  
2
votes

Have you looked at the DirectoryInfo class?

Specifically DirectoryInfo.Parent and DirectoryInfo.Root may help at discovering the root directory so you can remove it from FullName

Parent: http://msdn.microsoft.com/en-us/library/system.io.directoryinfo.parent.aspx

Root: http://msdn.microsoft.com/en-us/library/system.io.directoryinfo.root.aspx

0
votes

I don't know about safety, but I'd personally put it into a string, look for a contains("\\") or ':' and remove them from the string by substringing around them.

0
votes

As of request, here is how I did it:

I've written a helper class PathHelper that does what I think that the asker wants to know.

You can find the library on CodeProject, the function I would use is PathHelper.GetDriveOrShare, in a manner similar to:

var s = @"C:\foo\bar";
var withoutRoot = s.Substring( PathHelper.GetDriveOrShare(s).Length );