中の技術日誌
 ホーム / 上へ

わんくまライブラリ Wankuma.IO.Pathクラス Version1

2006/01/29

この文書はVisual Studio 2003(.NET1.1)をベースに記述されています。それ以降のバージョンや、あなたが読んでいる時点では変更されている可能性があります。
またバージョンアップされている場合にはなんらかかの不具合を含んでいる可能性があります。

新バージョンへ
Wankuma.IO.Path2d.htm

ドキュメントへ
Wankuma.IO.Path1d.htm

ソースファイル直接ダウンロードへ
Wankuma.IO.Path1c.txt

利用規約へ
../kiyaku.htm

using System;

namespace Wankuma.IO
{
  /// <summary>
  /// Path関連のクラスです。
  /// </summary>
  public class Path
  {
    /// <summary>
    /// 絶対パス2つから相対パスを導き出します。
    /// </summary>
    /// <param name="BasePath"></param>
    /// <param name="TargetPath"></param>
    /// <returns></returns>
    public static string PathAbsoluteRelative(string BasePath, string TargetPath)
    {
      //パスのルートが同じでないと相対化できないので、お互いのルートを調べて例外を発生させる
      string BasePathRoot = System.IO.Path.GetPathRoot(BasePath);
      string TargetPathRoot = System.IO.Path.GetPathRoot(TargetPath);
      if ( BasePathRoot != TargetPathRoot )
      {
        throw new ArgumentException("双方のパスが関連のないパスです。", "BasePath TargetPath");
      }

      string[] BasePathSplit;
      string[] TargetPathSplit;
      {
        //c:\a\等の場合には最後の区切り文字のせいで、誤判定をするので削除する
        string BasePathWithOutEndsSeparator = RemoveEndsSeparator(BasePath);
        string TargetPathWithOutEndsSeparator = RemoveEndsSeparator(TargetPath);

        //ルート部分を両方から切除します
        string BasePathWithOutRoot = BasePathWithOutEndsSeparator.Substring(BasePathRoot.Length);
        string TargetPathWithOutRoot = TargetPathWithOutEndsSeparator.Substring(BasePathRoot.Length);

        //UNCの場合には先頭文字が\マークで終わってしまうので、先頭の\マークも除去する
        if ( BasePathWithOutRoot[0] == '\\' )
        {
          BasePathWithOutRoot = BasePathWithOutRoot.Substring(1);
        }
        if ( TargetPathWithOutRoot[0] == '\\' )
        {
          TargetPathWithOutRoot = TargetPathWithOutRoot.Substring(1);
        }
        //パス区切り文字で分割します。
        BasePathSplit = BasePathWithOutRoot.Split(System.IO.Path.DirectorySeparatorChar );
        TargetPathSplit = TargetPathWithOutRoot.Split(System.IO.Path.DirectorySeparatorChar );
      }


      int LoopCounter = 0;
      for ( LoopCounter = 0; LoopCounter < BasePathSplit.Length; LoopCounter++ )
      {
        if ( TargetPathSplit.Length <= LoopCounter)
        {
          break;
        }
        //二つのパス文字列を比較する、同じであれば問題ないが、同じでなければそこでパスの同一性が失われたことになり、breakする
        if ( BasePathSplit[LoopCounter] != TargetPathSplit[LoopCounter] )
        {
          break;
        }
      }

      
      bool UpperFlag = false;
      bool BelowFlag = false;
      if ( BasePathSplit.Length > LoopCounter && TargetPathSplit.Length > LoopCounter )
      {
        //どちらでもないという場合には根が同じ分岐されたディレクトリと判断できる
        System.Diagnostics.Debug.WriteLine("分岐");
        UpperFlag = true;
        BelowFlag = true;
      }
      else if ( BasePathSplit.Length > LoopCounter )
      {
        //ベースパスの方が長い場合対象パスはベースパスより上にあると判断できる
        System.Diagnostics.Debug.WriteLine("上");
        UpperFlag = true;
      }
      else if ( TargetPathSplit.Length > LoopCounter )
      {
        //対象の方が長いという場合にはベースより下にあると判断できる
        System.Diagnostics.Debug.WriteLine("下");
        BelowFlag = true;
      }
      else
      {
        throw new Exception();
      }
      
      PathBuilder pb = new PathBuilder();
      //パスの連結作業を行う
      if ( UpperFlag == true )
      {
        for ( int UppePathLoopCounter = 0; UppePathLoopCounter < BasePathSplit.Length - LoopCounter; UppePathLoopCounter++)
        {
          pb.Append("..");
        }
      }
      if ( BelowFlag == true )
      {
        for ( int BelowPathLoopCounter = LoopCounter ; BelowPathLoopCounter < TargetPathSplit.Length; BelowPathLoopCounter++ )
        {
          pb.Append(TargetPathSplit[BelowPathLoopCounter]);
        }

      }

      return pb.ToString();
    }


    /// <summary>
    /// パス文字列の最後の文字が区切り文字でなければ区切り文字を追加します
    /// c:\ -> c:\, c:\a -> c:\a\
    /// </summary>
    /// <param name="path">対象のパス文字列</param>
    /// <returns>区切り文字付加済みのパス文字列</returns>
    public static string AddEndsSeparator(string path)
    {
      if ( path == null )
      {
        throw new ArgumentNullException("path", "pathにnullは指定できません");
      }
      if ( path == string.Empty )
      {
        throw new ArgumentException("path", "pathはemptyに出来ません。");
      }
      
      if ( path.EndsWith(System.IO.Path.DirectorySeparatorChar.ToString()) == true )
      {
        return path;
      }
      else
      {
        return path + System.IO.Path.DirectorySeparatorChar;
      }

    }
    /// <summary>
    /// パス文字列の最後の文字が区切り文字であれば区切り文字を削除します
    /// c:\ -> c:, c:\a -> c:\a
    /// c:\等の場合には意図しない動作をする可能性があるので注意。あくまで文字列の最後の文字だけを判定します。
    /// </summary>
    /// <param name="path">対象のパス文字列</param>
    /// <returns>区切り文字削除済みのパス文字列</returns>
    public static string RemoveEndsSeparator(string path)
    {
      if ( path == null )
      {
        throw new ArgumentNullException("path", "pathにnullは指定できません");
      }
      if ( path == string.Empty )
      {
        throw new ArgumentException("path", "pathはemptyに出来ません。");
      }
      
      if ( path.EndsWith(System.IO.Path.DirectorySeparatorChar.ToString()) == true )
      {
        return path.Substring(0, path.Length - 1);
      }
      else
      {
        return path;
      }

    }

  }


}

勉強会: 05/18 大阪 登録受付中

中の技術日誌
コンテンツ
わんくま同盟
わんくま同盟
わんくま同盟
広告
バナー
MVP LOGO
MSMVP Visual C# Since 2004/04-2007/03
MCP LOGO
070-316
姉妹サイト
姉妹サイト:じゃんぬのC#, VB.NET 入門
じゃんぬの
C#, VB.NET 入門
検索
Google

ブログ本家
広告