unlink,link,symlink等,處理檔案和目錄

miguelmin發表於2009-01-17
刪除檔案perl中用unlink運算子刪除檔案,同shellrm命令一樣。
unlink "aa","bb","cc";
把這三個檔案刪除。
glob函式結合起來可以一次刪除多個檔案
unlink glob "*.o";
刪除當前目錄下以.o結尾的檔案,與rm *.o相似。

unlink
的返回值告訴我們有多少檔案被成功刪除。
my $successful = unlink "aa","bb","cc";
print "I delete $successful file(s) just now.n";
[@more@]如果想知道那個檔案被刪除,可用迴圈,一次刪除一個檔案。
foreach my $file (qw/aa,bb,cc/) {
unlink $file or warn "failed on $file:$!";
}
一個很少人知道的有關unix的事實。如果你有一個檔案,你對它不能讀,不能寫,不能執行,甚至檔案可能並不屬於你,但你仍然可以刪除它。這是因為unlink一個檔案的許可權不依賴於檔案本身的許可權位,起作用的其實是包含這個檔案的目錄的許可權位。只要目錄是可寫的,就可以刪除該目錄中不屬於自已的檔案。在unix中可以透過設定sticky bit解這個問題,以保護可寫目錄。
重新命名檔案
rename "old","new";
類似於mv命令。rename失敗時返回假,並在$!中設定作業系統的錯誤資訊。因此可用or die or warn顯示給使用者。
一個把所有以.old結尾的東西rename為以.new結尾的perl程式。
foreach my $file (glob "*.old") {
my $newfile = $file;
$newfile =~ s/.old$/.new/;
由於.new不是模式,所以點號不用加反斜槓。
if (-e $newfile) {
warn "can't rename $file to $newfile:$newfile exists.n";
} elsif ( rename $file, $newfile) {
} else {
warn "rename $file to $newfile failed:$!n";
}
}
連結和檔案每個檔案都被存在一個編了號的inode中,每個inode都包含一個稱為連結計數(link count)的數字,當inode沒有列在任何目錄中時,連結計數總是0,也就是空,可以分配給檔案。當inode被加到一個目錄中時,連結計數會遞增;如果此列表項被刪除,連結計數會遞減。目錄包含.,也就是指向自已的inode,所以目錄的連結計數應該總是至少為2。檔案也可以不止一個列表項,如連結檔案。在perl中用link "aa","bb"建立一個指向aa的連結bb。類似於在unix shell一執行"ln aa bb"。現在aa,bb都有相同的inode值,兩個檔案有相同的大小,相同的內容。在aa中加入一行,也會在bb中加入一行。如果意外刪除了aa,資料並不會丟失,可以在bb中找回來。反之也一樣。但如果兩個檔案都刪除了,則資料就會丟失。
目錄列表項中的連結規則
1
一個給定的目錄列表項中的inode號都指向同一個安裝捲上的inode。這條規則保證,如果物理媒介被移到了另一臺機器上,所有的目錄仍和它們的檔案呆在一起。這就是為什麼可用rename把檔案從一個目錄移到另一個目錄的原因,但兩個目錄必須在同一個檔案系統(安裝卷)中連結不能用於目錄。
2
、不能給目錄起新的名字。因此目錄不能用於連結。以上討論的是硬連結,還有一個符號連結,也叫軟連結,能繞過這硬連線的限制。
symlink "aa","bb";
or warn "cannot symlink aa to bb:$!";
這和unix shell 中的"ln -s aa bb" 類似。
要想知道符號連結指向哪裡,可以使用readlin函式。如果不是符號連結,則返回undef
兩種連結都要以用unlink刪除。
建立和刪除目錄
mkdir
函式可以在一個已有的目錄中建立一個目錄。返回真時表示成功。
mkdir "aaa",0755 or warn "cannot make aaa directory:$!";
第二個引數是新生成目錄的許可權位。以0開頭,這個是一個八進位制值。

oct
函式強制對一個字串按八進位制解釋,不論前面有沒有0
刪除空目錄,可用rmdir函式。
rmdir glob "aa/*";
刪除aa/下所有空目錄。

rmdir
運算子對非空目錄操作會失敗。所以要先用unlink刪除檔案,再刪除目錄。
修改許可權
perl
中有一個chmod函式,和unix shell中的chmod完成類似功能。
chmod 0755, "aa","bb";
perl
中不接受符號許可權表示式方式,如+x,go=u-w等。
改變所有者
chown
函式可以改變一組檔案的所有者和屬組。
chown 1004,100,glob "*.o";
可用getpwnam把使用者名稱翻譯成一個數字,用getgrnam函式把組名翻譯成一個數字。
改變時間戳
utime
函式可修改檔案的訪問時間和修改時間。
my $now = time;
my $ago = $now -24*60*60;
每天的秒數
utime $now,$ago,glob "*";
把訪問時間設為現在,修改時間設為一天以前
第三個時間ctime的值在對檔案做任何改變時,總被設為現在,因此沒辦法用utime函式來設定它。因為在你設定完後它會立即被重置為“現在”,這是因為它的主要目的就是進行增量備份:如果檔案的ctime比備份磁帶上的日期要新,就說明又需要備份了。
使用簡單的模組
File::Basename
模組 從檔名中抽取基名,取不包括路徑的檔名。透過use命令宣告一個模組
use File::Basename;
這樣,我們就有了一個basename函式。
my $name = "/usr/local/bin/perl";
my $basename = basename $name;
得到perl該函式可用於多平臺,如windows
該模組中還有一個dirname函式,它把目錄名從一個完整檔名中分離出來。
有選擇地使用模組中的函式當你不需要模組中的所有函式,或模組中的函式和你程式中子例程有衝突時,你可以在宣告模組時給模組一個引入列表,只包括需要的函式。
use File::Basename qw /basename/;
只要basename函式,不要其它函式。
use File::Basename qw //;
不要任何函式。怎麼會想要一個空列表呢?這是因為,有引入只是使得我們能使用短的簡單的函式名,basename,dirname。即使不引入這些名字,我們仍可以使用,只是在沒有引入時,我們要用全名來呼叫它,如:File::Basename::dirname每個模組都有預設的引入列表,查相關文件有介紹。

File::Spec
模組用來處理檔案規範(file specification)。它是一個OO的模組。用小箭頭而不是::來引用函式。$newname = File::Spec->catfile($dirname,$basename);

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/16723161/viewspace-1016240/,如需轉載,請註明出處,否則將追究法律責任。

相關文章