C# - 폴더 경로 문자열에서 "..", "." 표기를 고려한 최종 문자열을 얻는 방법 - 두 번째 이야기
예전에 다음의 글을 쓴 적이 있는데요.
C# - 폴더 경로 문자열에서 "..", "." 표기를 고려한 최종 문자열을 얻는 방법
; https://www.sysnet.pe.kr/2/0/1808
그래서 Path.GetFullPath나 Uri 타입의 LocalPath를 이용하면 ".", ".." 경로를 정규화할 수 있습니다. 그런데, 이게 유닉스 계열의 경로에 대해서는 반환을 잘 하지 못합니다. 가령 다음과 같은 문자열이 있을 때,
string txt = "/home/tester/bin/x64/Debug/../test.conf";
Path.GetFullPath나 Uri 타입을 사용하면 결과가 이렇게 나옵니다.
Path.GetFullPath
C:\home\tester\bin\x64\test.conf
Uri.LocalPath - 예외 발생
System.UriFormatException: Invalid URI: The format of the URI could not be determined.
at System.Uri.CreateThis(String uri, Boolean dontEscape, UriKind uriKind)
at System.Uri..ctor(String uriString)
...[생략]...
물론, 위의 결과는 윈도우에서 실행했을 때입니다. Linux에서 실행하면 정상적으로 다음과 같이 정규화된 경로를 얻을 수 있습니다.
Path.GetFullPath
/home/tester/bin/x64/test.conf
Uri.LocalPath
/home/tester/bin/x64/test.conf
그래도 가끔은 윈도우 환경에서 리눅스 경로를 함께 다뤄야 할 수도 있는데요. 어쩔 수 없습니다. 이런 경우에는 만들어야지. ^^
using System;
using System.Collections.Generic;
using System.IO;
class Program
{
static void Main(string[] args)
{
string txt = "/home/tester/bin/x64/Debug/../test.conf";
NoException(Path.GetFullPath, txt);
NoException((path) => new Uri(path).LocalPath, txt);
NoException(NormalizePath, txt);
}
private static void NoException(Func<string, string> normalizePath, string path)
{
try
{
Console.WriteLine(normalizePath(path));
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
Console.WriteLine();
}
internal static string NormalizePath(string path)
{
List<string> pathList = new List<string>();
string[] parts = path.Split(new char[] { '/', '\\' }, StringSplitOptions.None);
foreach (string part in parts)
{
if (part == ".")
{
continue;
}
if (part == ".." && pathList.Count >= 1)
{
pathList.RemoveAt(pathList.Count - 1);
continue;
}
pathList.Add(part);
}
return string.Join('/'.ToString(), pathList.ToArray());
}
}
[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]