例えば「C:\Windows\System\..\file.txt」を「C:\Windows\file.txt」に変換するように、パスの中に、現在のディレクトリを表す"."や、親ディレクトリを表す".."が入っている時、これらを含まないパスに変換する(正規化する)方法を紹介します。
FileInfoクラスを使うと、パスの正規化ができます。
'正規化するパス Dim targetPath As String = "C:\Windows\.\System\..\file.txt" 'FileInfoオブジェクトを作成する Dim fi As New System.IO.FileInfo(targetPath) '絶対パスを取得する Console.WriteLine(fi.FullName) 'C:\Windows\file.txt
//正規化するパス string targetPath = @"C:\Windows\.\System\..\file.txt"; //FileInfoオブジェクトを作成する System.IO.FileInfo fi = new System.IO.FileInfo(targetPath); //絶対パスを取得する Console.WriteLine(fi.FullName); //C:\Windows\file.txt
ちょっと変わった使い方ですが、Path.GetFullPathメソッドを使ってもパスの正規化ができます。
'正規化するパス Dim targetPath As String = "C:\Windows\.\System\..\file.txt" '絶対パスを取得する Console.WriteLine(System.IO.Path.GetFullPath(targetPath)) 'C:\Windows\file.txt
//正規化するパス string targetPath = @"C:\Windows\.\System\..\file.txt"; //絶対パスを取得する Console.WriteLine(System.IO.Path.GetFullPath(targetPath)); //C:\Windows\file.txt
パスを正規化するWin32 APIに、PathCanonicalize functionがあります。P/InvokeでPathCanonicalize関数を使う方法は、「pinvoke.net: PathCanonicalize (shlwapi)」が参考になります。
'Imports System.Text 'Imports System.Runtime.InteropServices <DllImport("shlwapi.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _ Private Shared Function PathCanonicalize( _ <Out> lpszDest As StringBuilder, _ lpszSrc As String) As Boolean End Function ''' <summary> ''' 指定されたパスを正規化します。 ''' </summary> ''' <param name="filePath">正規化するパス。</param> ''' <returns>正規化されたパス。</returns> Public Shared Function NormalizePath(filePath As String) As String Dim sb As New StringBuilder(260) Dim res As Boolean = PathCanonicalize(sb, filePath) If Not res Then Throw New Exception("パスの正規化に失敗しました。") End If Return sb.ToString() End Function
//using System.Text; //using System.Runtime.InteropServices; [DllImport("shlwapi.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern bool PathCanonicalize( [Out] StringBuilder lpszDest, string lpszSrc); /// <summary> /// 指定されたパスを正規化します。 /// </summary> /// <param name="filePath">正規化するパス。</param> /// <returns>正規化されたパス。</returns> public static string NormalizePath(string filePath) { StringBuilder sb = new StringBuilder(260); bool res = PathCanonicalize(sb, filePath); if (!res) { throw new Exception("パスの正規化に失敗しました。"); } return sb.ToString(); }