在Mac OS和Windows 7上,R文件.mtime()精度极低

17

在Windows 7和Mac OS 10.12.2(使用R 3.3.2)上,似乎file.mtime()严重舍入或截断时间戳。我已验证,在Linux上,file.create("my_file.txt"); print(as.numeric(file.mtime("my_file.txt")), digits = 22)对于相同的my_file.txt可以打印出几个小数点后的数字,但在Windows 7上,小数点后面的所有内容都消失了。Mac OS 10.12.2的行为与Windows 7类似。是否有一种平台无关的方法来获取R中的精确文件时间戳?

2个回答

6
您可以等待大约2周,届时R 3.3.3将解决此问题(至少对于Windows系统而言)。从NEWS文件中得知:

(仅适用于Windows系统。)file.info()现在返回包括秒以下的时间戳;自R 2.14.0版本以来,在其他平台上已经这样做了。(注意:某些文件系统未记录修改和访问时间戳的亚秒分辨率。)


不错!那对于Windows来说很好。但对Mac OS,我可能就没那么幸运了。 - landau

3

我认为新的file.info很可能是最好的选择。如果R-3.3.3不能满足您的需求(或者在此期间,如果可以),您可以尝试通过利用stat通常安装在基本操作系统中的事实来绕过它(我没有在Mac上测试):

as.POSIXct(system2("stat", args = c("-c", "%y", "my_file.txt"), stdout = TRUE))
# [1] "2017-02-15 11:24:13 PST"

这可以用一个函数来形式化,它可以为您完成更多的工作:
my_mtime <- function(filenames, stat = c("modified", "birth", "access", "status"),
                     exe = Sys.which("stat")) {
  if (! nzchar(exe)) stop("'stat' not found")
  stat <- switch(match.arg(stat), birth = "%w", access = "%x", modified = "%y", status = "%z")
  filenames <- Sys.glob(filenames) # expand wildcards, remove missing files
  if (length(filenames)) {
    outs <- setNames(system2(exe, args = c("-c", stat, shQuote(filenames)), stdout = TRUE),
                     nm = filenames)
    as.POSIXct(outs)
  }
}

my_mtime("[bh]*")
#                  b-file.R                  h-file.R 
# "2017-02-14 05:46:34 PST" "2017-02-14 05:46:34 PST"

如果你要求 file.mtime,我假设“修改”对你来说最有趣,但是也很容易包括其他一些文件时间戳:

my_mtime("[bh]*", stat="birth")
#                  b-file.R                  h-file.R 
# "2017-02-13 22:04:01 PST" "2017-02-13 22:04:01 PST" 
my_mtime("[bh]*", stat="status")
#                  b-file.R                  h-file.R 
# "2017-02-14 05:46:34 PST" "2017-02-14 05:46:34 PST" 

请注意,缺少小数秒是打印的副产品(正如您所述),可以通过以下方法解决:

x <- my_mtime("[bh]*", stat="status")
x
#                  b-file.R                  h-file.R 
# "2017-02-14 05:46:34 PST" "2017-02-14 05:46:34 PST" 
options(digits.secs = 6)
x
#                         b-file.R                         h-file.R 
# "2017-02-14 05:46:34.307046 PST" "2017-02-14 05:46:34.313038 PST" 
class(x)
# [1] "POSIXct" "POSIXt" 

更新: 在Mac上测试后,我确认了一些事情(感谢@HongOoi的提示):(1) stat确实不同,不支持相同的命令行选项,因此需要更新此脚本; (2) 这个答案表明文件系统甚至没有存储文件时间的亚秒分辨率。如果您的文件系统类型是HFS +,我认为这里可能无法做任何事情。如果底层文件系统不同,则可能会获得更好的结果。

的确,Windows没有附带stat可执行文件。然而,一些人认为在分析/开发工具包中使用Git for Windows是必需的,并且它确实有/Program Files/Git/usr/bin/stat.exe。(实际上,我上面的hack是在Windows上编写的,在Ubuntu上进行了第二次测试。)

总之,不幸的是,根据您的文件系统类型,您可能无法在MacOS上获得所需的内容。我无法获得安装的stat以提供亚秒分辨率(即使使用不同的参数),这表明我引用的四年前的答案没有改变。


stat是Unix/Linux实用程序,在Windows上不存在。在Mac上,文件系统本身仅以1秒分辨率存储时间(直至APFS到来)。这基本上不会比R的file.info更多做任何事情。 - Hong Ooi
请注意,Visual Studio已经内置了git集成,因此您甚至不一定需要独立安装git。 - Hong Ooi
我不知道,谢谢。VS是否带有其他类unix的可执行文件,比如stat? (没有考虑到VS,因为它不在问题中,也许提问者可以使用这个。) - r2evans
不过,在Windows 10上,您可以在bash shell中使用stat本身。了解更多 - Hong Ooi
当然可以,而且你甚至可以在%HOME%\AppData\Local\lxss\rootfs\usr\bin\stat路径下“看到”可执行文件。要使用它,你需要在任何要进行stat操作的完整路径之前添加/mnt/c(相对路径需要转换)。所以你是对的,这在没有GfW安装的Windows上也可以工作,做得好。(由于与非bash子系统工具集成的困难,我一直避免使用bash子系统。) - r2evans
作为(晚期)的跟进:要让R能够使用基于WSL的实用程序,您需要在WSL本身内运行R。目前,Windows中的R可以执行Windows二进制文件;WSL中的R可以执行Linux二进制文件;两个系统都无法执行另一个二进制格式。因此,尽管@HongOoi关于能够使用WSL shell的评论是正确的,但它并不是没有限制或后果。 - r2evans

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接