How to get relative path from absolute path

前端 未结 23 1822
既然无缘
既然无缘 2020-11-22 11:52

There\'s a part in my apps that displays the file path loaded by the user through OpenFileDialog. It\'s taking up too much space to display the whole path, but I don\'t want

23条回答
  •  盖世英雄少女心
    2020-11-22 12:38

    You want to use the CommonPath method of this RelativePath class. Once you have the common path, just strip it out of the path you want to display.

    Namespace IO.Path
    
        Public NotInheritable Class RelativePath
    
            Private Declare Function PathRelativePathTo Lib "shlwapi" Alias "PathRelativePathToA" ( _
                ByVal pszPath As String, _
                ByVal pszFrom As String, _
                ByVal dwAttrFrom As Integer, _
                ByVal pszTo As String, _
                ByVal dwAttrTo As Integer) As Integer
    
            Private Declare Function PathCanonicalize Lib "shlwapi" Alias "PathCanonicalizeA" ( _
                ByVal pszBuf As String, _
                ByVal pszPath As String) As Integer
    
            Private Const FILE_ATTRIBUTE_DIRECTORY As Short = &H10S
    
            Private Const MAX_PATH As Short = 260
    
            Private _path As String
            Private _isDirectory As Boolean
    
    #Region " Constructors "
    
            Public Sub New()
    
            End Sub
    
            Public Sub New(ByVal path As String)
                _path = path
            End Sub
    
            Public Sub New(ByVal path As String, ByVal isDirectory As Boolean)
                _path = path
                _isDirectory = isDirectory
            End Sub
    
    #End Region
    
            Private Shared Function StripNulls(ByVal value As String) As String
                StripNulls = value
                If (InStr(value, vbNullChar) > 0) Then
                    StripNulls = Left(value, InStr(value, vbNullChar) - 1)
                End If
            End Function
    
            Private Shared Function TrimCurrentDirectory(ByVal path As String) As String
                TrimCurrentDirectory = path
                If Len(path) >= 2 And Left(path, 2) = ".\" Then
                    TrimCurrentDirectory = Mid(path, 3)
                End If
            End Function
    
            ''' 
            ''' 3. conforming to general principles: conforming to accepted principles or standard practice
            ''' 
            Public Shared Function Canonicalize(ByVal path As String) As String
                Dim sPath As String
    
                sPath = New String(Chr(0), MAX_PATH)
    
                If PathCanonicalize(sPath, path) = 0 Then
                    Canonicalize = vbNullString
                Else
                    Canonicalize = StripNulls(sPath)
                End If
    
            End Function
    
            ''' 
            ''' Returns the most common path between two paths.
            ''' 
            ''' 
            ''' returns the path that is common between two paths
            ''' c:\FolderA\FolderB\FolderC
            '''   c:\FolderA\FolderD\FolderE\File.Ext
            ''' 
            '''   results in:
            '''       c:\FolderA\
            ''' 
            Public Shared Function CommonPath(ByVal path1 As String, ByVal path2 As String) As String
                'returns the path that is common between two paths
                '
                '   c:\FolderA\FolderB\FolderC
                '   c:\FolderA\FolderD\FolderE\File.Ext
                '
                '   results in:
                '       c:\FolderA\
    
                Dim sResult As String = String.Empty
                Dim iPos1, iPos2 As Integer
                path1 = Canonicalize(path1)
                path2 = Canonicalize(path2)
                Do
                    If Left(path1, iPos1) = Left(path2, iPos2) Then
                        sResult = Left(path1, iPos1)
                    End If
                    iPos1 = InStr(iPos1 + 1, path1, "\")
                    iPos2 = InStr(iPos2 + 1, path1, "\")
                Loop While Left(path1, iPos1) = Left(path2, iPos2)
    
                Return sResult
    
            End Function
    
            Public Function CommonPath(ByVal path As String) As String
                Return CommonPath(_path, path)
            End Function
    
            Public Shared Function RelativePathTo(ByVal source As String, ByVal isSourceDirectory As Boolean, ByVal target As String, ByVal isTargetDirectory As Boolean) As String
                'DEVLIB
                '   05/23/05  1:47PM - Fixed call to PathRelativePathTo, iTargetAttribute is now passed to dwAttrTo instead of IsTargetDirectory.
                '       For Visual Basic 6.0, the fix does not change testing results,
                '           because when the Boolean IsTargetDirectory is converted to the Long dwAttrTo it happens to contain FILE_ATTRIBUTE_DIRECTORY,
                '
                Dim sRelativePath As String
                Dim iSourceAttribute, iTargetAttribute As Integer
    
                sRelativePath = New String(Chr(0), MAX_PATH)
                source = Canonicalize(source)
                target = Canonicalize(target)
    
                If isSourceDirectory Then
                    iSourceAttribute = FILE_ATTRIBUTE_DIRECTORY
                End If
    
                If isTargetDirectory Then
                    iTargetAttribute = FILE_ATTRIBUTE_DIRECTORY
                End If
    
                If PathRelativePathTo(sRelativePath, source, iSourceAttribute, target, iTargetAttribute) = 0 Then
                    RelativePathTo = vbNullString
                Else
                    RelativePathTo = TrimCurrentDirectory(StripNulls(sRelativePath))
                End If
    
            End Function
    
            Public Function RelativePath(ByVal target As String) As String
                Return RelativePathTo(_path, _isDirectory, target, False)
            End Function
    
        End Class
    
    End Namespace
    

提交回复
热议问题