[.net] Relative paths...

Started by
7 comments, last by alex_myrpg 18 years, 10 months ago
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
Advertisement
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\"
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.
thanks a lot for both your replies :) macoy, i thought of a similar method to that but your specific one seems perfect...
Check out:
System.IO.Directory
System.IO.DirectoryInfo (does what you want)
System.IO.File
System.IO.FileInfo

sounds like the sort of namespace i'd want, but i can't find the exact function. :S if you could specify exactly how i should use it in the context of my problem, that's be great :D
Please post finished code here :-D

ok, i guess there's no built in method, that's ok. i'll just use macoy's method then and it should work nicely :).
Here's my code for the solved problem:
'Get relative filenameProtected 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...

This topic is closed to new replies.

Advertisement