Creates a relative path from absolute pathfilename and a reference path.
/*
* Filename: FileUtil.cs
* Product: Versioning Controlled Build
* Solution: BuildAutoIncrement
* Project: Shared
* Description: File utility methods.
* Copyright: Julijan ?ribar, 2004-2007
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the author(s) be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
using System;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
namespace BuildAutoIncrement {
/// <summary>
/// A set of file utilities.
/// </summary>
public struct FileUtil {
/// <summary>
/// Creates a relative path from absolute pathfilename and a
/// reference path.
/// </summary>
/// <param name="pathfilename">
/// Absolute pathfilename for which relative pathfilename has to be
/// created.
/// </param>
/// <param name="referencePath">
/// Reference path.
/// </param>
/// <returns>
/// Returns relative pathfilename. If pathfilename and reference path
/// do not have common part (e.g. from different drive), absolute
/// filepathname is returned.
/// </returns>
public static string GetRelativePathfilename(string pathfilename, string referencePath) {
Debug.Assert(pathfilename != null && pathfilename.Length > 0);
Debug.Assert(referencePath != null && referencePath.Length > 0);
Debug.Assert(Path.IsPathRooted(pathfilename));
Debug.Assert(Path.IsPathRooted(referencePath));
// split both pathnames into directory names constituting path name
string[] pathfilenameSections = pathfilename.Split(DirectorySeparators);
string[] referencePathSections = referencePath.Split(DirectorySeparators);
StringBuilder relativePath = new StringBuilder();
int pathSectionCounter = 0;
// skip leading backslashes for the case of UNC path name
if (pathfilename.StartsWith("\\\\") && referencePath.StartsWith("\\\\"))
pathSectionCounter = 2;
int filenameSectionCounter = pathSectionCounter;
bool matchingFound = false;
// scan for common parts of paths
while ((pathSectionCounter < referencePathSections.Length) && (referencePathSections[pathSectionCounter].Length > 0)) {
if (string.Compare(referencePathSections[pathSectionCounter], pathfilenameSections[pathSectionCounter], true) == 0)
matchingFound = true;
else {
if (matchingFound) {
while ((pathSectionCounter < referencePathSections.Length) && (referencePathSections[pathSectionCounter].Length > 0)) {
relativePath.Append("..");
relativePath.Append(Path.DirectorySeparatorChar);
pathSectionCounter++;
}
}
break;
}
pathSectionCounter++;
filenameSectionCounter++;
}
// no common starting sections - return absolute path
if (!matchingFound)
return pathfilename;
// append filename path
while (filenameSectionCounter < pathfilenameSections.Length) {
relativePath.Append(pathfilenameSections[filenameSectionCounter]);
filenameSectionCounter++;
if (filenameSectionCounter < pathfilenameSections.Length)
relativePath.Append(Path.DirectorySeparatorChar);
}
return relativePath.ToString();
}
/// <summary>
/// Directory separator characters.
/// </summary>
public static readonly char[] DirectorySeparators = new char[] {Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar };
}
}
Related examples in the same category