如何在 .NET 中获得绝对或规范化的文件路径?

Posted

技术标签:

【中文标题】如何在 .NET 中获得绝对或规范化的文件路径?【英文标题】:How can one get an absolute or normalized file path in .NET? 【发布时间】:2010-11-18 23:54:05 【问题描述】:

如何以最小的努力(如果可能,使用一些现有的设施)将c:\aaa\bbb\..\ccc 之类的路径转换为c:\aaa\ccc

【问题讨论】:

【参考方案1】:

Path.GetFullPath 或许?

【讨论】:

我不相信这可以保证返回一个规范的名称。它只保证返回的名称可以用于绝对引用文件和相对引用文件 Path.GetFullPath(@"c:\aaa\bbb\..\ccc") = c:\aaa\ccc - 对我来说已经足够了。 @Henk:Path utils 实际上不应该检查有效文件,甚至不应该触及文件系统(但在少数情况下会这样做)。 @My-Name-Is:这完全取决于你如何使用它。 @My-Name-Is:这就是 GetFullPath 应该做的。注意 Path.GetFullPath(@"\..\aaa") 返回废话 "C:\..\aaa" 而 Path.GetFullPath(@"..\aaa") 返回相对于您的绝对路径 Path.CurrentDirectory( )【参考方案2】:

规范化是 .NET 中 Uri 类的主要职责之一。

var path = @"c:\aaa\bbb\..\ccc";
var canonicalPath = new Uri(path).LocalPath; // c:\aaa\ccc

【讨论】:

所以我假设这会检查路径是否确实存在? 不,Uri 类只负责生成路径。不考虑与这些路径相关的系统。通过我的答案中的方法获得路径后,您仍然需要通过 File 类(或其他)检查它是否存在。 请注意,驱动器字母大小写仍然无法正常化(例如,“C:\”和“c:\”都没有改变)。因此,无论如何,从独特的意义上说,这并不是真正的“规范”。 @AlastairMaw 由于 Windows FS 是 CI,假设路径是“规范的”,那么任何其他路径不同,仅大小写是规范和等效的即使有大小写差异.消费者还应该使用 CI 字符串比较,因为所有大小写不同的形式相同。【参考方案3】:

我会这样写:

public static string NormalizePath(string path)

    return Path.GetFullPath(new Uri(path).LocalPath)
               .TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)
               .ToUpperInvariant();

这应该可以处理一些场景,例如

    uri 和其中潜在的转义字符,例如

    file:///C:/Test%20Project.exe -> C:\TEST PROJECT.EXE

    由点指定的路径段表示当前或父目录

    c:\aaa\bbb\..\ccc -> C:\AAA\CCC

    波浪号缩短(长)路径

    C:\Progra~1\ -> C:\程序文件

    目录分隔符不一致

    C:/Documents\abc.txt -> C:\DOCUMENTS\ABC.TXT

除此之外,它可以忽略大小写,尾随\目录分隔符等。

【讨论】:

良好而简洁的路径规范化解决方案,正是我想要的。 +1 不要将 ToUpper() 和朋友用于您想要可移植的任何代码。世界上有区分大小写的文件系统。此外,如果您向用户显示这些值也不是很好,在这种情况下,您希望保留大小写并使用不区分大小写的排序和比较。否则,看起来不错。 这完全取决于您所说的“规范”是什么意思,但是,由于 Windows 将文件路径视为不区分大小写,我认为您 确实 需要大小写转换,否则它是同一个文件可能有多个“规范”路径。不过我更喜欢小写。 它不适用于相对路径。这样做: private string NormalizePath(string path) return path.Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar) .ToUpperInvariant(); @Andy:另一方面,如果有人使用NormalizePath 的这种变体将文件复制或移动到某个地方,她/他很可能希望大小写不会改变。作为用户,我会禁止任何更改我精心维护的家庭命名系统的此类程序。【参考方案4】:

FileInfo 对象也可以在这里提供帮助。 (https://docs.microsoft.com/en-us/dotnet/api/system.io.fileinfo?view=net-5.0)

var x = Path.Combine(@"C:\temp", "..\\def/abc");
var y = new FileInfo(x).FullName; // "C:\\def\\abc"

如果您想控制文件与目录的区别,FileInfo 与 DirectoryInfo 也有帮助。

但如果只需要字符串,Path.GetFullPath 会更好。

【讨论】:

以上是关于如何在 .NET 中获得绝对或规范化的文件路径?的主要内容,如果未能解决你的问题,请参考以下文章

什么是“规范路径”?

asp.net mvc 已知文件名,如何得到该文件的绝对路径。在线急等

python3.8 windows 如何获得txt的绝对路径?

如何使用 datePattern 在 log4net 中指定绝对文件路径?

java获取当前类的绝对路径

软件目录结构规范以及在不同目录间进行模块调用