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

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

【问题讨论】:

    标签: .net filepath


    【解决方案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();
    }
    

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

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

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

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

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

    3. 波浪号缩短(长)路径

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

    4. 目录分隔符不一致

      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 会更好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-22
      • 2014-07-28
      • 2014-06-28
      • 1970-01-01
      • 2017-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多