/*! @file Classes/System/IO/Path.ab @brief ファイルパス文字列を操作する @author OverTaker */ Namespace System Namespace IO Class Path Public Static Const AltDirectorySeparatorChar = &H2F As StrChar '/ Static Const DirectorySeparatorChar = &H5C As StrChar '\ Static Const PathSeparator = &H3B As StrChar '; Static Const VolumeSeparatorChar = &H3A As StrChar ': '---------------------------------------------------------------- ' パブリック メソッド '---------------------------------------------------------------- /* @brief 拡張子を変更する @param パス @param 変更する拡張子(.を含む) @return 拡張子変更後のパス */ Static Function ChangeExtension(path As String, extension As String) As String path = CheckPath(path) If HasExtension(path) Then Return path.Remove(GetExtensionIndex(path)) + extension Else Return path + extension End If End Function /* @brief 二つのパスを結合する @param 結合されるパス @param 結合するパス @return パス */ Static Function Combine(path1 As String, path2 As String) As String path1 = CheckPath(path1) path2 = CheckPath(path2) If IsPathRooted(path2) Then Return path2 Else If Not path1.EndsWith(DirectorySeparatorChar) Then path1 += Chr$(DirectorySeparatorChar) End If Return path1 + path2 End If End Function /* @brief パス文字列からファイル名を取得する @param パス @return ファイル名 */ Static Function GetFileName(path As String) As String path = CheckPath(path) Dim lastSeparatorIndex = GetLastSeparatorIndex(path) As Long If lastSeparatorIndex <> -1 Then Return path.Substring(lastSeparatorIndex + 1) Else Return path End If End Function /* @brief パス文字列からファイル名を拡張子を除いて取得する @param パス @return 拡張子を除いたファイル名 */ Static Function GetFileNameWithoutExtension(path As String) As String path = GetFileName(path) If HasExtension(path) Then Return path.Remove(GetExtensionIndex(path)) Else Return path End If End Function /* @brief 絶対パスを取得する @param 相対パス @return 絶対パス */ Static Function GetFullPath(path As String) As String Return Combine(System.Environment.CurrentDirectory, path) End Function /* @brief パス文字列から拡張子を取得する @param パス @return .を含む拡張子 */ Static Function GetExtension(path As String) As String path = CheckPath(path) Dim extensionIndex = GetExtensionIndex(path) If extensionIndex <> -1 Then Return path.Substring(extensionIndex) Else Return New String() End If End Function /* @brief ひとつ上のディレクトリを取得する @param パス @return ディレクトリパス */ Static Function GetDirectoryName(path As String) As String path = CheckPath(path) Dim lastSeparatorIndex = GetLastSeparatorIndex(path) If lastSeparatorIndex = -1 Then Return New String() Else Return path.Substring(0, lastSeparatorIndex) End If End Function /* @brief ルートディレクトリを取得する @param パス @return ルートディレクトリ */ Static Function GetPathRoot(path As String) As String path = CheckPath(path) If IsPathRooted(path) Then If path.Contains(UniformNamingConventionString) Then Return path.Remove(path.IndexOf(DirectorySeparatorChar, UniformNamingConventionString.Length) + 1) Else Return path.Remove(3) End If Else Return New String() End If End Function /*! @brief ランダムなファイル名を取得する @param ファイルパス @return ファイル名 手抜き実装 */ Static Function GetRandomFileName() As String Randomize Return Str$(((Rnd() * 900000000) As Long) + 10000000) End Function /*! @brief 一時ファイルを作成し、ファイルパスを取得する @return パス */ Static Function GetTempFileName() As String Dim tempFileName[ELM(MAX_PATH)] As TCHAR Dim len = WIN32API_GetTempFileName(GetTempPath(), "ABT", 0, tempFileName) If len <> 0 Then Return New String(tempFileName, len As Long) Else Throw New IOException("Path.GetTempFileName: Failed to GetTempFileName.") End If End Function /* @brief システムの一時フォルダのパス取得する @return パス */ Static Function GetTempPath() As String Dim size = WIN32API_GetTempPath(0, 0) Dim p = GC_malloc_atomic(SizeOf (TCHAR) * size) As PCTSTR Dim len = WIN32API_GetTempPath(size, p) If (len > size) or len = 0 Then Throw New IOException("Path.GetTempPath: Failed to GetTempPath.") Else Return New String(p, len As Long) End If End Function /* @brief パスに拡張子が含まれるかどうか @param パス @retval True 含まれる @retval False 含まれない */ Static Function HasExtension(path As String) As Boolean path = CheckPath(path) Return GetExtensionIndex(path) <> -1 End Function /* @brief パスが絶対パスか取得する @param パス @retval True 絶対パス @retval False 相対パス */ Static Function IsPathRooted(path As String) As Boolean path = CheckPath(path) Return path.Contains(UniformNamingConventionString) _ or path.Contains(VolumeSeparatorChar) _ or path.StartsWith(DirectorySeparatorChar) End Function Private Static Const ExtensionSeparatorChar = &H2E As StrChar Static Const InvalidPathChars = Ex"\q<>|\0\t" As String Static Const UniformNamingConventionString = Ex"\\\\" As String '---------------------------------------------------------------- ' プライベート メソッド '---------------------------------------------------------------- /* @brief パスに不正な文字が含まれていないか調べる。 @param パス @return 正しく直されたパス パス末端にディレクトリ区切り記号があった場合除去する ..\などが含まれるパスについては未実装 */ Static Function CheckPath(path As String) As String path = path.Replace(AltDirectorySeparatorChar, DirectorySeparatorChar) Dim i As Long For i = 0 To ELM(InvalidPathChars.Length) If path.Contains(InvalidPathChars.Substring(i, 1)) Then Throw New IOException("Path.CheckPath: The path contains invalidPathChars.") End If Next If path.LastIndexOf(UniformNamingConventionString) > 0 Then Throw New IOException("Path.CheckPath: The path is invalid value.") End If If path.EndsWith(DirectorySeparatorChar) Then Return path.Remove(path.Length - 1) Else Return path End If End Function /* @brief パスの最も後ろにあるディレクトリ区切り記号の位置を取得する @param パス @return インデックス */ Static Function GetLastSeparatorIndex(path As String) As Long Return System.Math.Max(path.LastIndexOf(DirectorySeparatorChar), path.LastIndexOf(AltDirectorySeparatorChar)) As Long End Function /* @brief 拡張子の位置を取得する。 @param パス @return インデックス */ Static Function GetExtensionIndex(path As String) As Long Dim extensionIndex = path.LastIndexOf(ExtensionSeparatorChar) As Long If extensionIndex > GetLastSeparatorIndex(path) Then Return extensionIndex Else Return -1 End If End Function End Class 'メソッドと名前が被るAPI Function WIN32API_GetTempPath(nBufferLength As DWord, lpBuffer As PTSTR) As DWord Return GetTempPath(nBufferLength, lpBuffer) End Function Function WIN32API_GetTempFileName (pPathName As PCTSTR, pPrefixString As PCTSTR, uUnique As DWord, pTempFileName As PTSTR) As DWord Return GetTempFileName(pPathName, pPrefixString, uUnique, pTempFileName) End Function End Namespace End Namespace