【问题标题】:Convert a relative path that includes a drive letter to an absolute path for .NET file functions将包含驱动器号的相对路径转换为 ​​.NET 文件函数的绝对路径
【发布时间】:2010-12-06 20:58:15
【问题描述】:

如何将诸如D:test.xml 之类的驱动器相对路径转换为诸如XDocument.Load() 之类的函数将接受的绝对路径。例如,D 驱动器可以将 D:\data 作为其当前工作目录,因此 D:test.xml 将意味着 D:\data\test.xml 。我已经尝试过D:.\test.xml 这样的混合物。

这是D:test.xml 之类的错误:

无效的 URI:Dos 路径必须有根,例如,'c:\'

【问题讨论】:

    标签: c# .net .net-4.0 c#-4.0


    【解决方案1】:

    您可以使用GetFullPath。例如:

    // should return "D:\data\test.xml" if the current working dir is "D:\data"
    string absolutePath = Path.GetFullPath("D:test.xml");
    

    如果 CWD 是 "D:\Data"Path.GetFullPath("D:test.xml") 确实会返回 "D:\data\test.xml",因为它会直接获取“test.xml”的完整路径。

    但是,如果使用与 CWD 不同的驱动器号,结果将不一致。例如Path.GetFullPath("C:test.xml") 将返回"C:\test.xml".

    这是设计使然。看看http://msdn.microsoft.com/en-us/library/aa365247.aspx#fully_qualified_vs._relative_paths

    如果文件名仅以磁盘指示符开头而不是 冒号后面的反斜杠,它被解释为一个相对路径 当前目录在具有指定字母的驱动器上。注意 当前目录可能是也可能不是根目录,具体取决于 在最近的“更改目录”期间设置的内容 在那个磁盘上操作

    [重点由我添加]

    【讨论】:

    【解决方案2】:

    您应该简单地使用“test.xml”作为相对路径,如果当前文件夹是“D:\data”,则完整路径将被解析为“D:\Data\test.xml”。 Load() 方法的 MSDN 示例中也说明了这一点:http://msdn.microsoft.com/en-us/library/bb343181.aspx

    请注意,“driveLetter:fileName”不是 .Net 中的相对路径。(请阅读更新)

    您可以使用 Path.GetFullPath() 将相对路径转换为完整路径,但您不必这样做 XDocument.Load(),因为它也会接受相对路径。

    更新 LukeH,感谢您指出这一点! "driveLetter:fileName" 被 Path.GetFullPath() 接受,并被计算为指定驱动器当前目录的相对路径,指定为 here

    驱动器级别的当前目录的概念是从非常古老的 DOS 继承而来的。不一定是我构建现代应用程序的功能。

    【讨论】:

    • 但是,当前工作目录位于不同的驱动器号上,因此此解决方案失败。
    • 当前目录如何在不同的驱动器上?它与什么在不同的驱动器上?您可以使用 Environment.CurrentDirectory 获取 .Net Windows 应用程序的当前目录。如果您在运行应用程序时不编辑该路径,它将是启动应用程序的路径。
    • 它与命令行上提供的驱动器号不同。例如,CWD 是 c:\test,arg 是 d:test.xml
    • 对不起,我还是没接你。您正在从“C:\test”启动应用程序,并且 xml 文件位于“D:\test\test.xml”中?
    • 是的,如果您在命令提示符下键入 d:,您将看到该 cmd 会话的 d:\test。
    【解决方案3】:

    Path.GetFullPath 可以工作。见the doc here

    【讨论】:

      【解决方案4】:

      正如 Luke 的 answer 中所述,解决方案取决于当前工作目录的使用方式。作为该答案的附录,这里有一些背景。当前工作目录是否为每个驱动器似乎有些奇怪。这是一个blog article from Raymond Chen of Microsoft 解释了这一点。

      我不得不四处挖掘才能找到一个好的链接,所以我也复制了内容以防万一。

      为什么每个驱动器都有自己的当前目录?

      评论者 Dean Earley 问道:“为什么会有‘当前目录’和 电流驱动器?为什么不合并它们呢?”

      精辟的回答:最初,每个驱动器都有自己的当前目录, 但现在他们没有,但看起来他们有。

      好的,让我们解开那句话。你其实知道的足以回答 自己的问题;您只需将各个部分组合在一起即可。

      将 Wayback 机器设置为 DOS 1.0。每个卷都由一个 驱动器号。没有子目录。这种行为被携带 从 CP/M 转发。

      DOS 1.0 时代的程序不理解子目录;他们 仅通过驱动器号和文件名引用文件,例如, B:程序.LST。让我们启动汇编器(编译器是为了丰富 people) 并汇编一个源代码在 A 驱动器上的程序, 但将输出发送到 B 驱动器。

      A>asm foo         the ".asm" extension on "foo" is implied
      Assembler version blah blah blah
      Source File: FOO.ASM
      Listing file [FOO.LST]: NUL       throw away the listing file
      Object file [FOO.OBJ]: B:     send the object file to drive B
      Since we gave only a drive letter in response to the Object file prompt, the assembler defaults to a file name of FOO.OBJ, resulting in
      

      目标文件被生成为 B:FOO.OBJ。

      好的,现在让我们在 DOS 2.0 中引入子目录。假设你 想组装 A:\SRC\FOO.ASM 并将结果放入 B:\OBJ\FOO.OBJ。以下是你的做法:

      A> B:
      B> CD \OBJ
      B> A:
      A> CD \SRC
      A> asm foo
      Assembler version blah blah blah
      Source File: FOO.ASM
      Listing file [FOO.LST]: NUL
      Object file [FOO.OBJ]: B:
      

      汇编器从 A:FOO.ASM 读取并写入 B:FOO.OBJ,但由于 当前目录在每个驱动器的基础上进行跟踪,结果是 A:\SRC\FOO.ASM 和 B:\OBJ\FOO.OBJ 根据需要。如果当前目录 没有在每个驱动器的基础上进行跟踪,那么就没有办法 告诉汇编器把它的输出放到一个子目录中。因此, DOS 1.0 程序实际上仅限于在 根目录,这意味着没有人会将文件放入 子目录(因为他们的程序无法访问它们)。

      从 DOS 1.0 的角度来看,更改驱动器上的当前目录 执行更改媒体的逻辑等效项。 “哦,看,一个 完全不同的文件集!”

      注意力持续时间短。

      记住每个驱动器的当前目录已被保留 从那时起,至少对于批处理文件,虽然实际上并没有 Win32 中的每个驱动器当前目录这样的概念。在 Win32 中, 你所拥有的只是一个当前目录。各驱动的样子 有自己的当前目录是由 cmd.exe 伪造的,它使用 奇怪的环境变量来创建批处理文件的错觉 每个驱动器都有自己的当前目录。

      Dean 继续说:“为什么不合并它们?我必须同时设置 dir 和 如果我想要一个特定的工作目录,请驱动。”

      第二个问题的答案是,“它们已经合并了。它是 cmd.exe 试图假装他们不是。”如果你想 从命令提示符或批处理设置目录和驱动器 文件,只需在 CHDIR 命令中使用 /D 选项:

      D:\> CD /D C:\Program Files\Windows NT
      C:\Program Files\Windows NT> _
      

      (请注意,CHDIR 命令允许您省略引号 包含空格的路径:由于该命令仅采用一个路径 论点,没有引号不会引起歧义。

      【讨论】:

        猜你喜欢
        • 2016-12-11
        • 2017-08-01
        • 2011-11-07
        • 2011-05-02
        相关资源
        最近更新 更多