前言
R語言作為腳本語言愧膀,有一套文件系統(tǒng)管理的功能函數(shù)檩淋,也可以實現(xiàn)如Python一樣的系統(tǒng)管理功能萄金。
本文將詳細(xì)介紹,R語言的文件系統(tǒng)管理日戈。試試有什么不樣吧孙乖?
目錄
文件系統(tǒng)介紹
目錄操作
文件操作
幾個特殊的目錄
1. 文件系統(tǒng)介紹
計算機的文件系統(tǒng)是一種存儲和組織計算機數(shù)據(jù)的方法,它使得對其訪問和查找變得容易鼓拧,文件系統(tǒng)使用文件和樹形目錄的抽象邏輯概念代替了硬盤和光盤等物理設(shè)備使用數(shù)據(jù)塊的概念越妈,用戶使用文件系統(tǒng)來保存數(shù)據(jù)不必關(guān)心數(shù)據(jù)實際保存在硬盤(或者光盤)的地址為多少的數(shù)據(jù)塊上,只需要記住這個文件的所屬目錄和文件名酌住。在寫入新數(shù)據(jù)之前酪我,用戶不必關(guān)心硬盤上的那個塊地址沒有被使用且叁,硬盤上的存儲空間管理(分配和釋放)功能由文件系統(tǒng)自動完成,用戶只需要記住數(shù)據(jù)被寫入到了哪個文件中逞带。
R語言和其他編程語言一樣展氓,都有對文件系統(tǒng)的操作,包括文件操作和目錄操作未妹,函數(shù)API都定義在base包中。
2. 目錄操作
系統(tǒng)環(huán)境:
Linux: Ubuntu Server 12.04.2 LTS 64bit
R: 3.0.1 x86_64-pc-linux-gnu
2.1 查看目錄
查看當(dāng)前目錄下的子目錄络它。
# 啟動R程序
~ R
# 當(dāng)前的目錄
> getwd()
[1] "/home/conan/R/fs"
# 查看當(dāng)前目錄的子目錄
> list.dirs()
[1] "."? ? "./tmp"
查看當(dāng)前目錄的子目錄和文件。
> dir()
[1] "readme.txt" "tmp"
# 查看指定目錄的子目錄和文件导梆。
> dir(path="/home/conan/R")
[1] "A.txt"? ? ? ? ? ? ? ? ? ? ? ? ? ? "caTools"
[3] "chinaWeather"? ? ? ? ? ? ? ? ? ? ? "DemoRJava"
[5] "env"? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "FastRWeb"
[7] "font"? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "fs"
[9] "github"? ? ? ? ? ? ? ? ? ? ? ? ? ? "lineprof"
[11] "pryr"? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "readme.txt"
[13] "RMySQL"? ? ? ? ? ? ? ? ? ? ? ? ? ? "RServe"
[15] "rstudio-server-0.97.551-amd64.deb" "websockets"
[17] "x86_64-pc-linux-gnu-library"
# 只列出以字母R開頭的子目錄或文件
> dir(path="/home/conan/R",pattern='^R')
[1] "RMySQL" "RServe"
# 列出目錄下所有的目錄和文件看尼,包括隱藏文件藏斩,如 .A.txt
> dir(path="/home/conan/R",all.files=TRUE)
[1] "."? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ".."
[3] ".A.txt"? ? ? ? ? ? ? ? ? ? ? ? ? ? "A.txt"
[5] "caTools"? ? ? ? ? ? ? ? ? ? ? ? ? "chinaWeather"
[7] "DemoRJava"? ? ? ? ? ? ? ? ? ? ? ? "env"
[9] "FastRWeb"? ? ? ? ? ? ? ? ? ? ? ? ? "font"
[11] "fs"? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "github"
[13] "lineprof"? ? ? ? ? ? ? ? ? ? ? ? ? "pryr"
[15] "readme.txt"? ? ? ? ? ? ? ? ? ? ? ? "RMySQL"
[17] "RServe"? ? ? ? ? ? ? ? ? ? ? ? ? ? "rstudio-server-0.97.551-amd64.deb"
[19] "websockets"? ? ? ? ? ? ? ? ? ? ? ? "x86_64-pc-linux-gnu-library"
查看當(dāng)前目錄的子目錄和文件却盘,同dir()函數(shù)。
> list.files()
[1] "readme.txt" "tmp"
> list.files(".",all.files=TRUE)
[1] "."? ? ? ? ? ".."? ? ? ? "readme.txt" "tmp"
查看完整的目錄信息兆览。
# 查看當(dāng)前目錄權(quán)限
> file.info(".")
size isdir mode? ? ? ? ? ? ? mtime? ? ? ? ? ? ? ctime? ? ? ? ? ? ? atime? uid? gid uname grname
. 4096? TRUE? 775 2013-11-14 08:40:46 2013-11-14 08:40:46 2013-11-14 08:41:57 1000 1000 conan? conan
# 查看指定目錄權(quán)限
> file.info("./tmp")
size isdir mode? ? ? ? ? ? ? mtime? ? ? ? ? ? ? ctime? ? ? ? ? ? ? atime? uid? gid uname grname
./tmp 4096? TRUE? 775 2013-11-14 14:35:56 2013-11-14 14:35:56 2013-11-14 14:35:56 1000 1000 conan? conan
2.2 創(chuàng)建目錄
# 在當(dāng)前目錄下塞关,新建一個目錄
> dir.create("create")
> list.dirs()
[1] "."? ? ? ? "./create" "./tmp"
創(chuàng)建一個3級子目錄./a1/b2/c3
# 直接創(chuàng)建帆赢,出錯
> dir.create(path="a1/b2/c3")
Warning message:
In dir.create(path = "a1/b2/c3") :
cannot create dir 'a1/b2/c3', reason 'No such file or directory'
# 遞歸創(chuàng)建,成功
> dir.create(path="a1/b2/c3",recursive = TRUE)
> list.dirs()
[1] "."? ? ? ? ? "./a1"? ? ? "./a1/b2"? ? "./a1/b2/c3" "./create"? "./tmp"
# 通過系統(tǒng)命令查看目錄結(jié)構(gòu)
> system("tree")
.
├── a1
│?? └── b2
│??? ? └── c3
├── create
├── readme.txt
└── tmp
2.3 檢查目錄是否存在
# 目錄存在
> file.exists(".")
[1] TRUE
> file.exists("./a1/b2")
[1] TRUE
# 目錄不存在
> file.exists("./aa")
[1] FALSE
2.4 檢查目錄的權(quán)限
檢查目錄的權(quán)限
> df<-dir(full.names = TRUE)
# 檢查文件或目錄是否存在怠益,mode=0
> file.access(df, 0) == 0
./a1? ? ./create ./readme.txt? ? ? ? ./tmp
TRUE? ? ? ? TRUE? ? ? ? TRUE? ? ? ? TRUE
# 檢查文件或目錄是否可執(zhí)行瘾婿,mode=1,目錄為可以執(zhí)行
> file.access(df, 1) == 0
./a1? ? ./create ./readme.txt? ? ? ? ./tmp
TRUE? ? ? ? TRUE? ? ? ? FALSE? ? ? ? TRUE
# 檢查文件或目錄是否可寫孩饼,mode=2
> file.access(df, 2) == 0
./a1? ? ./create ./readme.txt? ? ? ? ./tmp
TRUE? ? ? ? TRUE? ? ? ? TRUE? ? ? ? TRUE
# 檢查文件或目錄是否可讀竹挡,mode=4
> file.access(df, 4) == 0
./a1? ? ./create ./readme.txt? ? ? ? ./tmp
TRUE? ? ? ? TRUE? ? ? ? TRUE? ? ? ? TRUE
修改目錄權(quán)限立膛。
# 修改目錄權(quán)限,所有用戶只讀
> Sys.chmod("./create", mode = "0555", use_umask = TRUE)
# 查看目錄完整信息好啰,mode=555
>? file.info("./create")
size isdir mode? ? ? ? ? ? ? mtime? ? ? ? ? ? ? ctime? ? ? ? ? ? ? atime? uid? gid uname grname
./create 4096? TRUE? 555 2013-11-14 08:36:28 2013-11-14 09:07:05 2013-11-14 08:36:39 1000 1000 conan? conan
# create目錄不可以寫
> file.access(df, 2) == 0
./a1? ? ./create ./readme.txt? ? ? ? ./tmp
TRUE? ? ? ? FALSE? ? ? ? TRUE? ? ? ? TRUE
2.5 對目錄重名
# 對tmp目錄重命名
> file.rename("tmp", "tmp2")
[1] TRUE
# 查看目錄
> dir()
[1] "a1"? ? ? ? "create"? ? "readme.txt" "tmp2"
2.6 刪除目錄
# 刪除tmp2目錄
> unlink("tmp2", recursive = TRUE)
# 查看目錄
> dir()
[1] "a1"? ? ? ? "create"? ? "readme.txt"
2.7 其他功能函數(shù)
拼接目錄字符串
# 拼接目錄字符串
> file.path("p1","p2","p3")
[1] "p1/p2/p3"
> dir(file.path("a1","b2"))
[1] "c3"
獲取最底層的子目錄名
# 當(dāng)前目錄
> getwd()
[1] "/home/conan/R/fs"
# 最底層子目錄
> dirname("/home/conan/R/fs/readme.txt")
[1] "/home/conan/R/fs"
# 最底層子目錄或文件名
> basename(getwd())
[1] "fs"
>? basename("/home/conan/R/fs/readme.txt")
[1] "readme.txt"
轉(zhuǎn)換文件擴展路徑
# 轉(zhuǎn)換~為用戶目錄
> path.expand("~/foo")
[1] "/home/conan/foo"
標(biāo)準(zhǔn)化路徑框往,用來轉(zhuǎn)換win或linux的路徑分隔符
# linux
> normalizePath(c(R.home(), tempdir()))
[1] "/usr/lib/R"? ? ? "/tmp/RtmpqNyjPD"
# win
> normalizePath(c(R.home(), tempdir()))
[1] "C:\\Program Files\\R\\R-3.0.1"
[2] "C:\\Users\\Administrator\\AppData\\Local\\Temp\\RtmpMtSnci"
短路徑椰弊,縮減路徑的顯示長度,只在win中運行贤重。
# win
> shortPathName(c(R.home(), tempdir()))
[1] "C:\\PROGRA~1\\R\\R-30~1.1"
[2] "C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\RTMPMT~1"
3. 文件操作
3.1 查看文件
> dir()
[1]? "create"? "readme.txt"
# 檢查文件是否存在
> file.exists("readme.txt")
[1] TRUE
# 文件不存在
> file.exists("readme.txt222")
[1] FALSE
# 查看文件完整信息
> file.info("readme.txt")
size isdir mode? ? ? ? ? ? ? mtime? ? ? ? ? ? ? ctime? ? ? ? ? ? ? atime? uid? gid uname grname
readme.txt? ? 7 FALSE? 664 2013-11-14 08:24:50 2013-11-14 08:24:50 2013-11-14 08:24:50 1000 1000 conan? conan
# 查看文件訪問權(quán)限清焕,存在
>? file.access("readme.txt",0)
readme.txt
0
# 不可執(zhí)行
>? file.access("readme.txt",1)
readme.txt
-1
# 可寫
>? file.access("readme.txt",2)
readme.txt
0
# 可讀
>? file.access("readme.txt",4)
readme.txt
0
# 查看一個不存在的文件訪問權(quán)限秸妥,不存在
> file.access("readme.txt222")
readme.txt222
-1
判斷是文件還是目錄。
# 判斷是否是目錄
> file_test("-d", "readme.txt")
[1] FALSE
> file_test("-d", "create")
[1] TRUE
# 判斷是否是文件
> file_test("-f", "readme.txt")
[1] TRUE
> file_test("-f", "create")
[1] FALSE
3.2 創(chuàng)建文件
# 創(chuàng)建一個空文件 A.txt
> file.create("A.txt")
[1] TRUE
# 創(chuàng)建一個有內(nèi)容的文件 B.txt
> cat("file B\n", file = "B.txt")
> dir()
[1] "A.txt"? ? ? "B.txt"? ? ? "create"? ? "readme.txt"
# 打印A.txt
> readLines("A.txt")
character(0)
# 打印B.txt
> readLines("B.txt")
[1] "file B"
把文件B.txt的內(nèi)容铐刘,合并到 A.txt镰吵。
# 合并文件
> file.append("A.txt", rep("B.txt", 10))
[1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
# 查看文件內(nèi)容
> readLines("A.txt")
[1] "file B" "file B" "file B" "file B" "file B" "file B" "file B" "file B" "file B" "file B"
把文件A.txt復(fù)制到文件C.txt
# 復(fù)制文件
> file.copy("A.txt", "C.txt")
[1] TRUE
# 查看文件內(nèi)容
> readLines("C.txt")
[1] "file B" "file B" "file B" "file B" "file B" "file B" "file B" "file B" "file B" "file B"
3.3 修改文件權(quán)限
# 修改文件權(quán)限疤祭,創(chuàng)建者可讀可寫可執(zhí)行饵婆,其他人無權(quán)限
> Sys.chmod("A.txt", mode = "0700", use_umask = TRUE)
# 查看文件信息
> file.info("A.txt")
size isdir mode? ? ? ? ? ? ? mtime? ? ? ? ? ? ? ctime? ? ? ? ? ? ? atime? uid? gid uname grname
A.txt? 70 FALSE? 700 2013-11-14 12:55:18 2013-11-14 12:57:39 2013-11-14 12:55:26 1000 1000 conan? conan
3.4 文件重命名
# 給文件A.txt重命名為AA.txt
> file.rename("A.txt","AA.txt")
[1] TRUE
> dir()
[1] "AA.txt"? ? "B.txt"? ? ? "create"? ? "C.txt"? ? ? "readme.txt"
3.5 硬連接和軟連接
硬連接侨核,指通過索引節(jié)點來進行連接。在Linux的文件系統(tǒng)中搓译,保存在磁盤分區(qū)中的文件不管是什么類型都給它分配一個編號些己,稱為索引節(jié)點號(Inode Index)嘿般。在Linux中涯冠,多個文件名指向同一索引節(jié)點是存在的蛇更。一般這種連接就是硬連接。硬連接的作用是允許一個文件擁有多個有效路徑名派任,這樣用戶就可以建立硬連接到重要文件,以防止“誤刪”的功能痹兜。其原因如上所述字旭,因為對應(yīng)該目錄的索引節(jié)點有一個以上的連接崖叫。只刪除一個連接并不影響索引節(jié)點本身和其它的連接,只有當(dāng)最后一個連接被刪除后屈暗,文件的數(shù)據(jù)塊及目錄的連接才會被釋放养叛。也就是說宰翅,文件真正刪除的條件是與之相關(guān)的所有硬連接文件均被刪除汁讼。
軟連接,也叫符號連接(Symbolic Link)瓶珊。軟鏈接文件有類似于Windows的快捷方式耸彪。它實際上是一個特殊的文件。在符號連接中丑瞧,文件實際上是一個文本文件蜀肘,其中包含的有另一文件的位置信息扮宠。
硬連接和軟連接,只在Linux系統(tǒng)中使用获雕。
# 硬連接
> file.link("readme.txt", "hard_link.txt")
[1] TRUE
# 軟連接
> file.symlink("readme.txt", "soft_link.txt")
[1] TRUE
# 查看文件目錄
> system("ls -l")
-rwx------ 1 conan conan? 70 Nov 14 12:55 AA.txt
-rw-rw-r-- 1 conan conan? ? 7 Nov 14 12:51 B.txt
dr-xr-xr-x 2 conan conan 4096 Nov 14 08:36 create
-rw-rw-r-- 1 conan conan? 70 Nov 14 12:56 C.txt
-rw-rw-r-- 2 conan conan? ? 7 Nov 14 08:24 hard_link.txt
-rw-rw-r-- 2 conan conan? ? 7 Nov 14 08:24 readme.txt
lrwxrwxrwx 1 conan conan? 10 Nov 14 13:11 soft_link.txt -> readme.txt
文件hard_link.txt是文件readme.txt硬連接文件届案,文件soft_link.txt是文件readme.txt軟連接文件楣颠,
3.5 刪除文件
有兩個函數(shù)可以使用file.remove和unlink咐蚯,其中unlink函數(shù)使用同刪除目錄操作是一樣的童漩。
# 刪除文件
> file.remove("A.txt", "B.txt", "C.txt")
[1] FALSE? TRUE? TRUE
# 刪除文件
> unlink("readme.txt")
# 查看目錄文件
> system("ls -l")
total 12
-rwx------ 1 conan conan? 70 Nov 14 12:55 AA.txt
dr-xr-xr-x 2 conan conan 4096 Nov 14 08:36 create
-rw-rw-r-- 1 conan conan? ? 7 Nov 14 08:24 hard_link.txt
lrwxrwxrwx 1 conan conan? 10 Nov 14 13:11 soft_link.txt -> readme.txt
# 打印硬連接文件
> readLines("hard_link.txt")
[1] "file A"
# 打印軟連接文件,soft_link.txt春锋,由于原文件被刪除矫膨,有錯誤
> readLines("soft_link.txt")
Error in file(con, "r") : cannot open the connection
In addition: Warning message:
In file(con, "r") :
cannot open file 'soft_link.txt': No such file or directory
4. 幾個特殊的目錄
R.home() 查看R軟件的相關(guān)目錄
.Library 查看R核心包的目錄
.Library.site 查看R核心包的目錄和root用戶安裝包目錄
.libPaths() 查看R所有包的存放目錄
system.file() 查看指定包所在的目錄
4.1 R.home() 查看R軟件的相關(guān)目錄
# 打印R軟件安裝目錄
> R.home()
[1] "/usr/lib/R"
# 打印R軟件bin的目錄
> R.home(component="bin")
[1] "/usr/lib/R/bin"
# 打印R軟件文件的目錄
>? R.home(component="doc")
[1] "/usr/share/R/doc"
通過系統(tǒng)命令,找到R文件的位置期奔。
# 檢查系統(tǒng)中R文件的位置
~ whereis R
R: /usr/bin/R /etc/R /usr/lib/R /usr/bin/X11/R /usr/local/lib/R /usr/share/R /usr/share/man/man1/R.1.gz
# 打印環(huán)境變量R_HOME
~ echo $R_HOME
/usr/lib/R
通過R.home()函數(shù)侧馅,我們可以很容易的定位R軟件的目錄。
4.2 R軟件的包目錄
# 打印核心包的目錄
> .Library
[1] "/usr/lib/R/library"
# 打印核心包的目錄和root用戶安裝包目錄
> .Library.site
[1] "/usr/local/lib/R/site-library" "/usr/lib/R/site-library"
[3] "/usr/lib/R/library"
# 打印所有包的存放目錄
> .libPaths()
[1] "/home/conan/R/x86_64-pc-linux-gnu-library/3.0"
[2] "/usr/local/lib/R/site-library"
[3] "/usr/lib/R/site-library"
[4] "/usr/lib/R/library"
4.3 查看指定包所在的目錄
# base包的存放目錄
> system.file()
[1] "/usr/lib/R/library/base"
# pryr包的存放目錄
>? system.file(package = "pryr")
[1] "/home/conan/R/x86_64-pc-linux-gnu-library/3.0/pryr"
其實呐萌,用R語言操作文件系統(tǒng)還是很方便的馁痴。但對于函數(shù)命名確實不太規(guī)范,需要我們花時間記憶搁胆。