【问题标题】:Properly escape filepaths正确转义文件路径
【发布时间】:2014-08-08 09:19:56
【问题描述】:

使用变量时如何使用@-符号转义?

File.Delete(@"c:\test"); // WORKS!

File.Delete(@path); // doesn't work :(

File.Delete(@"c:\test"+path); // WORKS

有人知道吗?这是我要使用的第二个示例!

【问题讨论】:

  • 为什么要使用第二个例子?
  • 这里为什么需要使用文字串?它应该对File.Delete 调用产生零差异...
  • @Lasse:我猜他们认为在前面加上@ 是让字符串中的路径工作的魔法。像“总是在路径前加上@,否则它们不起作用”。我可以看到一个没有经过适当指导或培训的人可能会这样认为,完全没有注意到使该工作发挥作用的实际语言功能。而对于编译器@path 也没有错,只是出于其他原因。
  • 你需要注意你的第三个例子相当于(@"c:\test") + path
  • @James 这只是一个例子。我只是在我的头顶拿了一个随机函数来做一个例子

标签: c#


【解决方案1】:

@ 字符为前缀的字符串称为verbatim string literals(其内容无需转义)。

因此,您只能将@ 与字符串文字一起使用,而不是字符串变量。

所以,在您事先指定路径之后(从逐字字符串或其他字符串),只需 File.Delete(path); 即可。

【讨论】:

  • 哦,当然!谢谢先生。我不知道为什么我没有想到这个嘿嘿。
【解决方案2】:

逐字字符串只是一种语法技巧,可以更轻松地键入包含反斜杠(路径、正则表达式)的字符串。声明

string path = "C:\\test";
string path = @"C:\test";

它们的结果完全相同。两者都会产生一个包含C:\test 的字符串。请注意,任何一个选项都是必需的,因为 C# 语言将字符串中的 \ 视为特殊的。

@ 不是使路径正常工作所需的魔法小精灵,它在作为字符串前缀时具有定义的含义,因为字符串的解释没有通常的\ 转义序列。

你的第二个例子没有像你期望的那样工作的原因是@ 前缀到一个变量名做了一些不同的事情:它允许你使用保留关键字作为标识符,这样你就可以使用@class 作为标识符, 例如。对于不与关键字冲突的标识符,结果与没有冲突的结果相同。

如果你有一个包含路径的字符串变量,那么你通常可以假设根本不需要转义。毕竟它已经在一个字符串中。我上面提到的事情是在运行时通过编译器正确地将源代码中的文本获取到字符串中所需要的,因为编译器有不同的想法。字符串本身就是始终表示相同的数据。

这仍然意味着您必须以反斜杠存在的方式初始化字符串。如果您从某个地方读取它,则不需要特殊处理,如果您在代码中的其他地方将其作为常量字符串,那么再次,必须使用顶部的选项之一。

【讨论】:

    【解决方案3】:
    string path = @"c:\test"; 
    File.Delete(path); 
    

    这仅适用于字符串。 “真实”字符串是"c:\\test"

    阅读更多here

    【讨论】:

      【解决方案4】:

      您对@指标的理解存在重大问题。

      @"whatever string" 是一个文字字符串说明符逐字字符串文字。它的作用是告诉 C# 编译器不要寻找转义序列。通常,"\" 是字符串中的转义序列,您可以使用"\n" 来指示新行或"\t" 来指示制表符。但是,如果您有 @"\n",它会告诉编译器“不,我真的想将反斜杠视为反斜杠字符,而不是转义序列。”

      如果您不喜欢文字模式,则可以在任何需要单个反斜杠的地方使用"\\",因为编译器知道将转义的反斜杠视为单个字符。

      在任何一种情况下,@"\n""\\n" 都会在内存中生成一个包含两个字符的字符串,其中包含字符“\”和“n”。你去那里的方式并不重要。两者都是告诉编译器你想要这两个字符的方式。

      鉴于此,@path 没有任何意义,因为您没有任何文字字符 - 只是一个变量。当你有了变量时,你已经在内存中拥有了你想要的字符。正如 Joey 所解释的,它确实可以编译,但从逻辑上讲,它不是您要查找的内容。

      如果您正在寻找一种方法来消除变量中出现的\\,您只需要String.Replace

      string ugly = @"C:\\foo";
      ugly = ugly.Replace(@"\\", @"\");
      

      【讨论】:

      • 不错的答案。但是@"whatever string" 的技术术语是逐字字符串文字,而不是文字字符串
      • @Scott Mermelstein 你不必对我对@指标的理解感到粗鲁。我是在寻求帮助,而不是你对我缺乏技能的看法。
      • @DavidLarsson 我尽量避免粗鲁,如果您认为我是这样的话,我很抱歉。你是说你对@的理解没有大问题?这是我最粗鲁的言论。
      • @krumia 出于某种原因,当我在 Marcel 的回答中看到合适的术语时,我不想回去改变我的,但我现在已经在我的回答中修复了它。
      • @DavidLarsson:按照 StackOverflow 的标准,我不认为他是粗鲁的。我们不一定将缺乏对某事的理解视为缺乏技能。 :) 从您的问题中可以明显看出您缺乏理解,(这完全可以顺便说一句)。
      【解决方案5】:

      第一个和第三个是实际路径,因此可以工作。

      Second 甚至无法编译,如果

       string path = @"c:\test";
       File.Delete(path);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-02-28
        • 2016-09-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多