Relative Paths : Path « File Stream « C# / C Sharp






Relative Paths

      
/*
 * Copyright (c) United Binary LLC.  All rights reserved.
 * 
 * This code is licensed under the MIT License
 * 
 * SEE: http://harnessit.codeplex.com/license
 * 
 */
#region using ...
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Text;
#endregion

namespace UnitedBinary.Core.IO
{
  /// <include file='IO.xml' path='/Docs/RelativePaths/Class/*'/>
  public class RelativePaths
  {
    private string basepath = string.Empty;

    /// <include file='IO.xml' path='/Docs/RelativePaths/ctor_string/*'/>
    public RelativePaths(string basePath)
    {
      if (basePath == null || basePath.Length == 0)
      {
        throw new ArgumentException( "Invalid base path." );
      }

      BasePath = basePath;
    }

    /// <include file='IO.xml' path='/Docs/RelativePaths/ctor/*'/>
    public RelativePaths()
    {
    }

    /// <include file='IO.xml' path='/Docs/RelativePaths/GetRelativePath/*'/>
    public string GetRelativePath(string fullPath)
    {
      if (fullPath == null)
      {
        throw new ArgumentNullException( "fullPath" );
      }

      bool isCommonPath = CheckForCommonDrive( fullPath );
      bool isCommonNetwork = CheckForCommonNetworkPath( fullPath );
      if (!isCommonPath && !isCommonNetwork)
      {
        return fullPath;
      }

      char[] delims = {'\\'};
      string[] baseArray = BasePath.Split( delims );
      string[] fullArray = fullPath.Split( delims );
      int divergenceIndex = 0;
      for (int i=0; i < System.Math.Min( baseArray.Length, fullArray.Length ); i++)
      {
        if (string.Compare(baseArray[i], fullArray[i], true) != 0)
        {
          divergenceIndex = i;
          break;
        }
      }
      if (divergenceIndex == 0)
      {
        divergenceIndex = baseArray.Length;
      }

      int upCount = baseArray.Length - divergenceIndex;
      string relPath = string.Empty;
      for (int i=0; i < upCount; i++)
      {
        relPath += "..\\";
      }
      for (int i=divergenceIndex; i < fullArray.Length; i++)
      {
        relPath += fullArray[i];
        if (i < fullArray.Length-1)
        {
          relPath += "\\";
        }
      }

      Debug.WriteLine( "Divergence at index " + divergenceIndex );
      Debug.WriteLine( "Full path: " + fullPath );
      Debug.WriteLine( "Base path: " + BasePath );
      Debug.WriteLine( "Generated relative path: " + relPath );

      return relPath;
    }

    private bool CheckForCommonNetworkPath(string fullPath)
    {
      if (fullPath.Length == 0)
      {
        return false;
      }

      string basePath = BasePath;
      bool isBaseNetwork = basePath.StartsWith( @"\\" );
      bool isFullNetwork = fullPath.StartsWith( @"\\" );
      bool bothAreNetworks = isBaseNetwork && isFullNetwork;

      if (!bothAreNetworks)
      {
        return false;
      }

      int nextSlash = basePath.IndexOf( '\\', 2 );
      if (nextSlash < 0)
      {
        return false;
      }

      string commonRoot = basePath.Substring( 0, nextSlash + 1 );

      bool commonNetwork =
        string.Compare( basePath, 0, fullPath, 0, nextSlash+1, true ) == 0;

      return commonNetwork;
    }

    private bool CheckForCommonDrive(string fullPath)
    {
      if (fullPath.Length == 0)
      {
        return false;
      }

      string basePath = BasePath;
      bool isBaseDrive = basePath[1] == ':';
      bool isFullDrive = fullPath[1] == ':';

      bool bothAreDrives = isBaseDrive && isFullDrive;
      bool commonDrives =
        bothAreDrives &&
        char.ToLower(basePath[0]) == char.ToLower( fullPath[0] );

      if (bothAreDrives)
      {
        return commonDrives;
      }
      return false;
    }

    /// <include file='IO.xml' path='/Docs/RelativePaths/BasePath/*'/>
    public string BasePath
    {
      get
      {
        return basepath;
      }
      set
      {
        if (value == null)
        {
          throw new ArgumentNullException( "value" );
        }

        string startingSlashes = GetPrefixedSlashes( value.Trim() );

        basepath = value.Trim( new char[]  {' ', '\\'} );
        basepath = startingSlashes + basepath;
      }
    }

    private string GetPrefixedSlashes(string value)
    {
      StringBuilder sb = new StringBuilder();
      for (int i=0; i < value.Length; i++)
      {
        if (value[i] != '\\')
        {
          break;
        }
        else
        {
          sb.Append( '\\' );
        }
      }

      string startingSlashes = sb.ToString();
      return startingSlashes;
    }

    /// <include file='IO.xml' path='/Docs/Empty/Empty/*'/>
    [EditorBrowsable(EditorBrowsableState.Never)]
    public string DirectoryFromFileName(string fullPathName)
    {
      if (fullPathName == null || fullPathName.Length == 0)
      {
        throw new ArgumentException( "Invalid FullPathName." );
      }

      int dirIndex = fullPathName.Length;
      for (int i=fullPathName.Length-1; i > 0; i--)
      {
        if (fullPathName[i] == '\\')
        {
          dirIndex = i;
          break;
        }
      }

      if (dirIndex == fullPathName.Length)
      {
        return fullPathName;
      }

      string dir = fullPathName.Remove( dirIndex, fullPathName.Length - dirIndex );
      char[] trimmer = {'\\',' '};
      dir = dir.Trim( trimmer );

      Debug.WriteLine( "DirectoryFromFileName: Converted-> " + fullPathName );
      Debug.WriteLine( "DirectoryFromFileName: To--------> " + dir );

      return dir;
    }

    /// <include file='IO.xml' path='/Docs/RelativePaths/RebuildFullPath/*'/>
    public string RebuildFullPath(string relativeFilePath)
    {
      if (relativeFilePath == null || relativeFilePath.Length < 2)
      {
        return this.BasePath;
      }

      //
      // Check some special cases that don't fit the algorithm.
      // 1. The file is on a different drive than base (nothing relative to work with).
      // 2. The base path is a relative path itself.
      //
      if (relativeFilePath[1] == ':')
      {
        Debug.WriteLine( "Relative path contains drive letter - it is already a full path.  Returning." );
        return relativeFilePath;
      }
      else if (relativeFilePath.StartsWith(@"\\"))
      {
        Debug.WriteLine( "Relative path is a newtwork share - it is already a full path.  Returning." );
        return relativeFilePath;
      }

      if (BasePath.StartsWith(".."))
      {
        Debug.WriteLine( "Base is relative path, concatenating." );
        return BasePath + "\\" + relativeFilePath;
      }

      char[] splitter = {'\\'};
      string[] dirs = relativeFilePath.Split( splitter );
      int upCount = 0;
      foreach (string dir in dirs)
      {
        if (dir == "..")
        {
          upCount++;
        }
      }

      Debug.WriteLine( "Up count = " + upCount );

      StringBuilder sbFullPath2 = new StringBuilder();
      for (int i=upCount; i < dirs.Length; i++)
      {
        sbFullPath2.Append("\\").Append( dirs[i] );
      }
      string fullPath2 = sbFullPath2.ToString();

      Debug.WriteLine( "FullPath2 = " + fullPath2 );

      dirs = BasePath.Split( splitter );

      StringBuilder sbFullPath1 = new StringBuilder();
      sbFullPath1.Append( dirs[0] );
      for (int i=1; i < dirs.Length-upCount; i++)
      {
        sbFullPath1.Append("\\").Append( dirs[i] );
      }
      string fullPath1 = sbFullPath1.ToString();

      Debug.WriteLine( "FullPath1 = " + fullPath1 );

      string fullPath = fullPath1 + fullPath2;
      Debug.WriteLine( "FullPath = " + fullPath );

      return fullPath;
    }
  }
}

   
    
    
    
    
    
  








Related examples in the same category

1.Paths in C#
2.Path.GetTempFileName
3.Use static methods in Path
4.Resolve Path
5.Map Path
6.File Path Collection
7.Directory listing
8.Gets a list of files
9.Get Relative Path
10.Make Absolute Path
11.Combines two path strings.
12.Split the path into array of string
13.Get Application Relative Path
14.Performs operations on String instances that contain file or directory path information.
15.Get temp path
16.Get full path
17.Get temp file name
18.Combines two strings into a path.
19.Combines three strings into a path.
20.Combines four strings into a path.
21.Combines an array of strings into a path.
22.Get a list of invalid path characters.
23.Get a list of invalid file characters.
24.creates a relative path to "targetFile" that is relative to "path"
25.Creates a relative path from one file or folder to another.
26.Copies the specified resource to a temporary file and returns its path.
27.Is valid path name
28.Get Application Path
29.Calculate Relative Path
30.Combine paths
31.Gets the path of the current request relative to the application base path.
32.Redirects to a path relative to the application base path.
33.Gets the relative path from a source to a target path.
34.Gets the common root path of the given path list.
35.Checks if path provided corresponds to a directory.
36.Compares two rooted paths for equality. Any of the paths provided may end with path separator - it will be ignored.
37.Combines two paths, removing root-folder combinations.
38.Combine base Path and relative Path
39.Get Execution Path
40.Get relative path (2)
41.Formats the path.
42.Gets the relative path.
43.Checks a directory path and returns a normalized form with trailing
44.Returns the path argument adjusted to be relative to the base path. Absolute path names will be returned unchanged.