Skip to content

Instantly share code, notes, and snippets.

@karno
Created December 11, 2010 07:23
Show Gist options
  • Save karno/737217 to your computer and use it in GitHub Desktop.
Save karno/737217 to your computer and use it in GitHub Desktop.
using System;
using System.IO;
using System.Linq;
namespace EroTool.Logic
{
public static class PathExtension
{
/// <summary>
/// 相対パスへ変換します。
/// </summary>
/// <param name="path">対象パス</param>
/// <param name="dirbase">基準パス</param>
/// <returns>相対パス</returns>
public static string MakeRelative(string path, string dirbase)
{
// ルートディレクトリが違ったらどうしようもない
if (!Path.GetPathRoot(path).Equals(Path.GetPathRoot(dirbase), StringComparison.CurrentCultureIgnoreCase))
return path;
// 正規化
path = path.TrimEnd('\\');
dirbase = dirbase.TrimEnd('\\');
if (path.Equals(dirbase, StringComparison.CurrentCultureIgnoreCase))
{
// ディレクトリ自身
return ".\\";
}
if (path.StartsWith(dirbase, StringComparison.CurrentCultureIgnoreCase))
{
// pathはdirbaseの下にあります
// BASE: C:\Windows
// PATH: C:\Windows\System32\Base
// RELATIVE: System32\Base
return path.Substring(dirbase.Length + 1);
}
else
{
if (dirbase.StartsWith(path, StringComparison.CurrentCultureIgnoreCase))
{
// pathはdirbaseの上にあります
// BASE: C:\Windows\System32\Base
// PATH: C:\Windows
// RELATIVE: ..\..\
return new string('\\', (dirbase.Substring(path.Length + 1).Count((c) => c == '\\') + 1)).Replace("\\", "..\\");
}
else
{
// pathは全く違う可能性があります
// BASE: C:\Windows\System32\Base
// PATH: C:\Windows\SysWOW64
// RELATIVE: ..\..\SysWOW64
// (1) 分岐直前のパスを取得(Same)
// (2) Baseに対するSameの相対パス + Sameに対するRelativeの相対パス で取得
int i = 1;
while (
i < path.Length &&
i < dirbase.Length &&
dirbase.StartsWith(path.Substring(0, i), StringComparison.CurrentCultureIgnoreCase))
{
i++;
}
var same = path.Substring(0, i - 1);
return MakeRelative(same, dirbase) + MakeRelative(path, same);
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment