Sign in to follow this  
alex_myrpg

[.net] Relative paths...

Recommended Posts

Hi, What I would like to know is if there is a function (in the FileSystem namespace?) that can take a filename and different path and make the filename relative to this path. For example, taking: C:\Documents and Settings\My Name\My Documents\file.txt and C:\Documents and Settings\Test Directoryand generate the filename: ..\..\Test Directory\file.txt Hopefully there is a built in function for this, but I just cannot find one. If not, I'd be appreciative to hear any suggestions on efficient and reliable ways to do this... Thanks in advance, Alex

Share this post


Link to post
Share on other sites
This simple algorithm should work

Path1 = "C:\A\B\C\D\" <-- iam here
Path2 = "C:\A\B\E\"

1. Tokenize Paths

Path1_tokens = {"C:","A","B","C","D"}
Path2_tokens = {"C:","A","B","E"}

2. Delete equal Strings before first unequal

Path1_tokens = {"C","D"}
Path2_tokens = {"E"}

3. Replace Path1_tokens with ".."

Path1_tokens = {"..",".."}
Path2_tokens = {"E"}

Result = Path1_tokens + Path2_tokens = "\..\..\E\"

Share this post


Link to post
Share on other sites
I don't think such a function exists in the framework.

But Macoy's solution is correct.
Note that the Tokenizing could simply be done with one call to the Split function, if you know that all separator are '\'.
You also have to check that both path have the same drive as root, otherwise no relative path from one to the other exists.

Share this post


Link to post
Share on other sites
Here's my code for the solved problem:
'Get relative filename
Protected Function GetRelativeFilename(ByVal filename As String, ByVal relativePath As String) As String
Dim sPath1 As String = IO.Path.GetDirectoryName(filename)
Dim sPath2 As String = IO.Path.GetDirectoryName(relativePath)
Dim sPath1Tokens As String() = sPath1.Split(IO.Path.DirectorySeparatorChar)
Dim sPath2Tokens As String() = sPath2.Split(IO.Path.DirectorySeparatorChar)
Dim iTokenIndex As Integer, iTokenUB As Integer
Dim bPathChanged As Boolean
Dim sPathBack As String = ""
Dim sPathForward As String = ""

If IO.Path.GetPathRoot(sPath1).ToLower() <> IO.Path.GetPathRoot(sPath2).ToLower() Then
Return filename
End If

iTokenUB = Math.Max(sPath1Tokens.GetUpperBound(0), sPath2Tokens.GetUpperBound(0))

For iTokenIndex = 0 To iTokenUB
If iTokenIndex <= sPath1Tokens.GetUpperBound(0) Then
If bPathChanged Then
sPathBack &= ".." & IO.Path.DirectorySeparatorChar
End If
ElseIf Not bPathChanged Then
bPathChanged = True
End If
If iTokenIndex <= sPath2Tokens.GetUpperBound(0) Then
If bPathChanged Then
sPathForward &= sPath2Tokens(iTokenIndex) & IO.Path.DirectorySeparatorChar
End If
ElseIf Not bPathChanged Then
bPathChanged = True

sPathBack &= ".." & IO.Path.DirectorySeparatorChar
End If

If Not bPathChanged Then
If sPath1Tokens(iTokenIndex).ToLower() <> sPath2Tokens(iTokenIndex).ToLower() Then
bPathChanged = True

sPathBack &= ".." & IO.Path.DirectorySeparatorChar
sPathForward &= sPath2Tokens(iTokenIndex) & IO.Path.DirectorySeparatorChar
End If
End If
Next

Return sPathBack & sPathForward & IO.Path.GetFileName(filename)
End Function

thanks again for the help :) though it was a bit trickier than i thought to implement...

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this