为什么File.dirname会在我期望路径时返回句点?

时间:2013-12-16 18:35:57

标签: ruby

我正在尝试使用File.dirname获取Windows框中文件的目录。我从Windows框中获取文件(下面的“file1”)并将其返回到运行脚本的Mac OS X框中。

下面的

file1 = "C:\Administrator\proj1\testFile.txt"是为了简化我的示例,但为了使其更清晰,我从远程框中获取此值并将其返回到我的开发框:

file1 = "C:\Administrator\proj1\testFile.txt"
path = "#{File.dirname(file1)}"
puts "#{path}"

>> .

我很困惑为什么它会返回'.'。我在ruby-doc.org上看到File.dirname说了以下内容:

  

“返回file_name中给出的文件名的所有组件,除了最后一个。当File :: ALT_SEPARATOR不为nil时,可以使用File :: SEPARATOR和File :: ALT_SEPARETOR作为分隔符来形成文件名。”

我在putsFile::SEPARATOR上做了File::ALT_SEPARATOR并获得了以下内容:

File::SEPARATOR >> /
File::ALT_SEPARATOR >> 

我认为这是因为“\”不是有效的文件分隔符。所以我将File::ALT_SEPARATOR设置为“\”。然而,即使在那之后,我puts path时仍然得到相同的值。

我尝试使用File.realdirpath,这就是结果:

file1 = "C:\Administrator\proj1\testFile.txt"
path = "#{File.realdirpath(file1)}"
puts "{path}"

>>  /Users/me/myProject/C:\Administrator\proj1\testFile.txt

它似乎添加了我调用Ruby脚本的路径并附加了完整路径(包括文件名)。似乎是奇怪的行为。

任何想法,意见或建议都会很棒。

4 个答案:

答案 0 :(得分:0)

问题在于,当您声明file1时,这些反斜杠定义了转义字符。请注意返回:

file1 = "C:\Administrator\proj1\testFile.txt"
=> "C:Administratorproj1\testFile.txt"

如果要在字符串中存储文件路径,则需要使用正斜杠或双反斜杠(以转义转义字符):

file1 = "C:\\Administrator\\proj1\\testFile.txt"
file1 = "C:/Administrator/proj1/testFile.txt"

答案 1 :(得分:0)

好的,我也能够复制这个问题。

正如@fbonetti指出的那样,你必须用单引号括起你的目录,以防止ruby将反斜杠解释为转义,所以从那开始......

>> file1='C:\Administrator\proj1\testFile.txt'
=> "C:\\Administrator\\proj1\\testFile.txt"

然后,将file1传递给gsub以“斜线”标准化,为您提供您期望的结果。

>> File.dirname(file1.gsub('\\', '/'))
=> "C:/Administrator/proj1"

当然,如果你需要再次使用反斜杠,你总是可以反转gsub。

>> File.dirname(file1.gsub('\\', '/')).gsub('/', '\\')
=> "C:\\Administrator\\proj1"

答案 2 :(得分:0)

我明白了。这是我使用的Ruby版本的一个问题。我使用ruby 1.9.3然后我切换到jruby 1.7.3并且它现在正常工作。

答案 3 :(得分:0)

在处理不同的OS路径分隔符时,Ruby的IO文档非常有用。来自the documentation

  如果可能,Ruby将在不同的操作系统约定之间转换路径名。例如,在Windows系统上,文件名“/gumby/ruby/test.rb”将打开为“\ gumby \ ruby​​ \ test.rb”。在Ruby字符串中指定Windows样式的文件名时,请记住转义反斜杠:

"c:\\gumby\\ruby\\test.rb"
  

我们这里的例子将使用Unix风格的正斜杠; File :: ALT_SEPARATOR可用于获取特定于平台的分隔符。

因此,换句话说,您不需要使用反斜杠,以及是否需要使用单引号或双引号。保持简单,使用正斜杠让Ruby担心它。这样,您的代码可以在* nix / Mac OS和Windows上移植。

除此之外,看起来真的需要了解双引号字符串与单引号字符串中的字符转义是如何工作的。这来自“Programming Ruby”:

  

Ruby提供了许多用于创建文字字符串的机制。每个都生成String类型的对象。不同的机制在字符串的分隔方式和文字内容的替换次数方面各不相同。

     

单引号字符串文字('stuff'和%q / stuff /)经历了最少的替换。两者都将序列转换为单个反斜杠,带单引号的表单将\'转换为单引号。

'hello' »   hello
'a backslash \'\\\''    »   a backslash '\'
%q/simple string/   »   simple string
%q(nesting (really) works)  »   nesting (really) works
%q no_blanks_here ; »   no_blanks_here
  

双引号字符串(“stuff”,%Q / stuff /和%/ stuff /)会进行其他替换,如第20页的表18.2所示。

     

双引号字符串中的替换

\\a Bell/alert   (0x07) \\nnn     Octal nnn
\\b Backspace    (0x08) \\xnn     Hex nn
\\e Escape       (0x1b) \\cx      Control-x
\\f Formfeed     (0x0c) \\C-x     Control-x
\\n Newline      (0x0a) \\M-x     Meta-x
\\r Return       (0x0d) \\M-\\C-x Meta-control-x
\\s Space        (0x20) \\x       x
\\t Tab          (0x09) #{expr}   Value of  expr
\\v Vertical tab (0x0b)


a  = 123
"\123mile"  »   Smile
"Say \"Hello\"" »   Say "Hello"
%Q!"I said 'nuts'," I said! »   "I said 'nuts'," I said
%Q{Try #{a + 1}, not #{a - 1}}  »   Try 124, not 122
%<Try #{a + 1}, not #{a - 1}>   »   Try 124, not 122
"Try #{a + 1}, not #{a - 1}"    »   Try 124, not 122