R是一门著名的可用于数据和统计分析的程序语言,本文翻译自R软件官方文档教程《An Introduction to R》,仅供学习和参考。
14 操作系统工具
R 有相当广泛的工具来访问它运行的操作系统:这允许它用作脚本语言,并且 R 本身经常使用这种能力,例如安装包。
因为 R 自己的脚本需要在所有平台上工作,所以已经付出了相当大的努力来使脚本工具尽可能独立于平台。
14.1 文件和目录
有许多操作文件和目录的函数。以下是一些常用的。
要创建(空)文件或目录,请使用 file.create()
或 dir.create()
。 (这些是 POSIX 实用程序 touch
和 mkdir
的类似物。)对于 R 会话目录中的临时文件和目录,请参阅 tempfile()
。
可以通过 file.remove()
或 unlink()
删除文件:后者可以删除目录树。
对于目录列表,请使用 list.files()
(也可用作 dir()
或 list.dirs()
。这些可以使用正则表达式选择文件:使用 Sys.glob
按通配符选择。
file.info()
可以找到关于文件路径的许多类型的信息(包括例如它是文件还是目录)。
有几种方法可以查明文件是否“存在”(文件可以存在于文件系统中并且对当前用户不可见)。有函数 file.exists()
、file.access()
和 file_test()
以及此测试的各种版本:file_test()
是POSIX程序 test
命令的一个版本。
函数 file.copy()
是 POSIX 命令 cp
的 R 类似物。
选择文件可以通过 file.choose()
交互完成:Windows 端口具有更通用的函数 choose.files()
和 choose.dir()
,并且在 tcltk
包中有类似的函数:tk_choose.files()
和 tk_choose.dir()
。
函数 file.show
和 file.edit
将以适合 R 端口的方式显示和编辑一个或多个文件,使用控制台的工具(例如 Windows 上的 RGui 或 macOS 上的 R.app)(如果正在使用)。
对文件系统的链接提供了一定支持:参见函数 file.link()
和 Sys.readlink()
。
14.2 文件路径
除了少数例外,R 依赖于底层操作系统函数来操作文件路径。允许这方面的某些方面依赖于操作系统,甚至可以依赖于操作系统的版本。
有关于操作系统应如何解释文件路径的 POSIX 标准,许多 R 用户假定符合 POSIX:但 Windows 并未声称兼容,其他操作系统可能不完全兼容。
以下是文件路径相关的一些问题:
- POSIX 文件系统区分大小写,因此 foo.png 和 Foo.PNG 是不同的文件。但是,Windows 和 macOS 上的默认设置不区分大小写,而 FAT 文件系统(通常用于可移动存储)通常不区分大小写(并且所有文件路径都可能映射为小写)。
- 几乎所有的 Windows 操作系统服务都支持使用斜杠或反斜杠作为文件路径分隔符,R 将已知异常转换为 Windows 要求的形式。
- 带有尾部斜杠的文件路径的行为取决于操作系统。此类路径在 Windows 上无效,不应期望有效。 POSIX-2008 要求此类路径仅匹配目录,但早期版本允许它们也匹配文件。所以最好避免使用它们。
- 文件路径中的多个斜杠(例如 /abc//def)在 POSIX 文件系统上是有效的,并且被视为只有一个斜杠。它们通常被 Windows 的操作系统功能所接受。但是,前导双斜线可能有不同的含义。
- 不支持 Windows 的 UNC 文件路径(例如 \\server\dir1\dir2\file 和 \?\UNC\server\dir1\dir2\file),但它们可能适用于某些 R 函数。允许 POSIX 文件系统特殊处理前导双斜杠。
- Windows 允许文件路径包含磁盘驱动器并相对于驱动器上的当前目录,例如如果驱动器 d: 上的当前目录是 /a/b/c,则 d:foo/bar 指的是 d:/a/b/c/foo/bar。一般而言这是被允许的,但使用绝对路径更安全。
函数 basename()
和 dirname()
选择文件路径的一部分:从组件组装文件路径的推荐方法是file.path()
。函数 pathexpand()
执行“波浪号扩展”,替换主目录(当前用户的,可能还有其他用户的)的值。
在具有链接的文件系统上,单个文件可以被多个文件路径引用。函数 normalizePath()
将找到一个规范的文件路径。
Windows 有短文件名和长文件名的概念:normalizePath()
将返回使用长文件名的绝对路径,而 shortPathName()
将返回使用短文件名的版本。后者不包含空格并使用反斜杠作为分隔符,因此有时可用于从 R 中导出名称。
文件权限是一个相关主题。 R 支持所有者/组/所有人的读/写/执行权限的 POSIX 概念,但这在文件系统上可能仅部分支持,因此例如在 Windows 上仅只读文件(对于运行 R 会话的帐户)被认可。访问控制列表 (ACL) 用于多个文件系统,但没有一致的标准,R 也没有控制它们的工具。使用 Sys.chmod()
更改权限。
14.3 系统命令
函数 system()
和 system2()
用于调用系统命令并选择性地收集其输出。 system2()
更通用一些,但它的主要优点是使用它更容易编写跨平台代码。
系统在 Windows 上的行为与其他操作系统不同(因为该名称的 API C 调用确实如此)。在其他地方,它调用一个 shell 来运行命令:R 的 Windows 端口有一个函数 shell()
来执行此操作。
要查明操作系统是否包含命令,请使用 Sys.which()
,它试图以跨平台的方式执行此操作(不幸的是,它不是标准的操作系统服务)。
函数 shQuote()
将根据当前操作系统中命令的需要引用文件路径。
14.4 压缩和归档
R 的最新版本具有广泛的功能来读取和写入压缩文件,这通常是透明的。在 R 中读取文件在很大程度上是通过链接完成的,file()
函数用于打开到文件(或 URL)的链接,并且能够从文件的标头中识别使用的压缩技术。
支持时间最长的压缩类型是 gzip
压缩,它仍然是一个很好的通用折衷方案。也可以读取由早期 Unix 压缩实用程序压缩的文件,但这些文件越来越少。其他两种压缩形式,即bzip2
和 xz
实用程序也可用。它们通常以更慢的解压缩和更慢的压缩为代价实现更高的压缩率(更多的取决于文件)。
xz
和 lzma
压缩之间存在一些混淆(参见 https://en.wikipedia.org/wiki/Xz 和 https://en.wikipedia.org/wiki/LZMA):R 可以读取由它们的大多数版本压缩的文件。
文件存档是包含文件集合的单个文件,最常见的是用于分发 R 包的“tarball”和 zip 文件。 R 可以列出和解压缩两者(请参阅函数 untar()
和 unzip()
)并创建两者(在外部程序的帮助下进行 zip()
)。