Skip to content

Instantly share code, notes, and snippets.

@chiepomme
Last active May 25, 2020 11:12
Show Gist options
  • Save chiepomme/d6f7583c7af93e94bc5de30f95c9f996 to your computer and use it in GitHub Desktop.
Save chiepomme/d6f7583c7af93e94bc5de30f95c9f996 to your computer and use it in GitHub Desktop.
Convert an absolute path to a relative path.
using System;
using System.IO;
using System.Text;
public static class PathUtil
{
public static string AbsoluteToRelative(DirectoryInfo baseDir, FileInfo target)
{
var baseParts = baseDir.FullName.Replace('/', '\\').TrimEnd('\\').Split('\\');
var targetParts = target.FullName.Replace('/', '\\').Split('\\');
var relativePathBuilder = new StringBuilder();
// find common root depth
var depth = 0;
for (; depth < Math.Min(baseParts.Length, targetParts.Length); depth++)
{
if (baseParts[depth] != targetParts[depth]) break;
}
// move upward from base dir
for (var i = 0; i < baseParts.Length - depth; i++)
{
relativePathBuilder.Append(@"..\");
}
// move downward to target
for (var i = depth; i < targetParts.Length; i++)
{
relativePathBuilder.Append(targetParts[i]);
if (i + 1 != targetParts.Length)
{
relativePathBuilder.Append(@"\");
}
}
return relativePathBuilder.ToString();
}
}
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.IO;
[TestClass]
public class PathUtilTest
{
[TestMethod]
public void ShouldConvertAbsolutePathToRelativePath()
{
Assert.AreEqual(@"file.txt", PathUtil.AbsoluteToRelative(new DirectoryInfo(@"C:\A\B\C"), new FileInfo(@"C:\A\B\C\file.txt")));
Assert.AreEqual(@"D\file.txt", PathUtil.AbsoluteToRelative(new DirectoryInfo(@"C:\A\B\C"), new FileInfo(@"C:\A\B\C\D\file.txt")));
Assert.AreEqual(@"..\..\file.txt", PathUtil.AbsoluteToRelative(new DirectoryInfo(@"C:\A\B\C"), new FileInfo(@"C:\A\file.txt")));
Assert.AreEqual(@"..\..\D\file.txt", PathUtil.AbsoluteToRelative(new DirectoryInfo(@"C:\A\B\C"), new FileInfo(@"C:\A\D\file.txt")));
Assert.AreEqual(@"file.txt", PathUtil.AbsoluteToRelative(new DirectoryInfo(@"C:\A\B\C\"), new FileInfo(@"C:\A\B\C\file.txt")));
Assert.AreEqual(@"D\file.txt", PathUtil.AbsoluteToRelative(new DirectoryInfo(@"C:\A\B\C\"), new FileInfo(@"C:\A\B\C\D\file.txt")));
Assert.AreEqual(@"..\..\file.txt", PathUtil.AbsoluteToRelative(new DirectoryInfo(@"C:\A\B\C\"), new FileInfo(@"C:\A\file.txt")));
Assert.AreEqual(@"..\..\D\file.txt", PathUtil.AbsoluteToRelative(new DirectoryInfo(@"C:\A\B\C\"), new FileInfo(@"C:\A\D\file.txt")));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment