#

只要是撰寫稍微大一點的程式,說真的很難避免掉一些檔案或目錄的操作,特別是檔案總管或FTP一類的程式更是會大量的使用。Tcl提供了數個非常容易使用而且功能強大的檔案系統操作命令,使用這些命令你可以很容易的維護檔案的屬性、目錄的列表或執行檔案複製、刪除或搬移...等等,甚至是用來寫個檔案總管也夠用了。這一篇文章將介紹cd、pwd、glob及file等4個Tcl裡很常用的檔案及目錄相關命令。

12.1 工作目錄操作

玩過Unix-like系統的人一定都會知道pwd及cd的功能,它們分別可以用來取得目前的工作目錄以及改變目前的工作目錄。在Tcl裡同樣也提供這兩個命令,而且功能也是相同的。

pwd命令的語法:

pwd

pwd命令回傳目前的工作目錄,使用時不需要加任何參數。

cd命令的語法:

cd ?dirName?

cd命令用來切換目前的工作路徑到dirName指定的位置,dirName必需是一個存在的目錄,若dirName沒有指定則切換到家目錄。cd命令回傳空字串。

程式範例:



程式輸出:

/private/tmp
/Users/dai

上面的程式輸出會根據正在使用的作業系統及狀況而有所差別。

12.2 目錄列表

Tcl使用glob命令來提供像dir或ls一樣的目錄列表命令,它的語法如下:

glob ?switches? pattern ?pattern ...?

glob搜尋指定目錄下符合pattern的所有檔案及目錄,並以清單的方式回傳搜尋的結果。switches是選擇性的參數用來調整glob的功能,pattern是由關鍵字及特殊字元所組成的字串,它被用來比對搜尋的項目。以下是pattern可以使用的特殊字元:

?符合任意單一字元。
*符合任意長度的任意字元。
[chars]符合chars字元集合(字串)裡的任一字元。
\x符合字元x。
{a,b,...}符合任一大括號內的字串。

switches可以使用的參數如下:

-directory directory 使用directory當成要搜尋的目標目錄,若沒有指定則使用目前的工作目錄。
-join 以目錄分隔字元把所有的pattern組合為單一pattern,再執行搜尋。
-nocomplain 如果glob命令執行時沒有找到任何檔案或目錄,它會抱怨找不到檔案。加上-nocomplain告訴glob不要產生抱怨訊息。
-path pathPrefix 搜尋時把pathPrefix串接在pattern的開頭,且不解釋pathPrefix內的特殊字元。
-tails 讓回傳的清單只包含檔名及目錄名稱而不包含路徑。
-types typeList 限定搜尋的檔案類型,必需要為包含以下字元的清單:b(block special file)、c(character special file)、d(directory)、f(plain file)、l(symbolic link)、p(named pipe)、s(socket)、r(可讀)、w(可寫)、x(可執行)、readonly(唯讀)、hidden(隱藏檔)。
- - (短線間沒有空白) switches的結束符號。

以下的範例在不同的電腦上可能會有不同的輸出,所以就不把輸出的結果打在文件上了,請大家自己試試看。

在Windows下列出c:/下所有的檔案及目錄:



在Linux下列出家目錄下所有的目錄:



在Linux下列出指定目錄下所有的MP3檔案:



在Windows下列出c:/mp3資料夾內的所有MP3檔案:



注意哦!! Tcl就算在Windows下目錄分隔的符號也要用「/」而不是「\」。

12.3 檔案及目錄基礎操作

file命令提供了一套檔案及目錄的處理功能,它讓你可以很輕鬆的執行檔案命名、刪除、搬移以及屬性設定...等操作。另外file也提供了數個檔案路徑相關的處理功能,例如:切割及組合檔案的路徑、讀取符號連結甚至是判別檔案所在的檔案系統...等等。在接下來的說明裡會常常出現「檔案路徑」這個名詞,如果沒有特別說明的話它是指檔案或目錄的路徑。

□ 檔案及目錄複製

file copy提供了檔案及目錄複製的功能,它的語法如下:

file copy ?-force? ?- -? source target

source是來源項目的檔案路徑,target是要複製的目的地。如果目的地已經有相同的項目,加上-force可以強迫覆蓋已經存在的項目,否則的話程式會產生錯誤。file copy有兩種運作模式:

  1. 如果target是一個已存在的目錄,那source會被複製到target目錄裡面。
  2. 如果target是一個不存在的檔案或目錄,那source被複製到target的父目錄下,並用target的檔名部份命名。

假設/tmp是一個已經存在的目錄,那下面的例子都會套用第一種運作模式:



假設b2.txt不存在。下面的例子都會套用第二種運作模式:



除了一次操作一個檔案外,file copy也允許你一次複製N個檔案。它的語法如下:

file copy ?-force? ?- -? source ?source ...? targetDir

source是要複製的來源,targetDir是要複製的目的地,所有的來源項目都會被複製到targetDir裡面。注意!! 在多個檔案的操作情況下,targetDir一定要是一個已經存在的目錄,否則程式會產生錯誤。-force同樣用來指定要複蓋已存在的項目。

程式範列:


□ 刪除檔案及目錄

file delete提供了檔案及目錄刪除的功能,它的語法如下:

file delete ?-force? ?- -? pathname ?pathname ... ?

pathname是要刪除的項目,若要刪除的內容是目錄而且目錄裡還有其它的項目,指定-force表示要連同目錄裡的項目一併刪除。

程式範列:



□ 重新命名

file rename提供了檔案及目錄重新命名的功能,切確的說它的行為更像是檔案的搬移。事實上這個命令的用法和file copy是一樣的,只是file copy會保留來源項目,而file rename則會刪除來源的項目。它的語法也和file copy是一樣的:

file rename ?-force? ?- -? source target file rename ?-force? ?- -? source ?source ...? targetDir

程式範列:


□ 建立檔案連結

file link提供了建立連結的功能,它的語法如下:

file link ?-linktype? linkName ?target?

linkName是要建立的連結檔案,target是要連結的目標。如果沒有指定target的話,那file link會把linkName當成是一個已存在的連結檔案,然後回傳它的連結目標。linktype是要建立連結的種類, 它的值可以是「-symbolic」或「-hard」,預設是-symbolic。

Linux下的程式範列:



□ 讀取檔案連結

file readlink提供了讀取連結的功能,並回傳連結的目標路徑。它的語法如下:

file readlink name

程式範例:



□ 建立目錄

file mkdir提供了建立目錄的功能。它的語法如下:

file mkdir dir ?dir ...?

dir是要建立的目錄。如果要建立的目錄已經存在,file命令會產生錯誤。

程式範列:



□ 其它常用的操作

file exists可以用來判斷檔案或目錄是否存在,是的話回傳1,否則回傳0:



file isdirectory 可以用來判斷某個檔案路徑是不是目錄,是的話回傳1,否則回傳0:



file isfile 可以用來判斷某個檔案路徑是不是檔案,是的話回傳1,否則回傳0:



file pathtype name :分析檔案路徑是absolute、relative還是volumerelative。



file size 回傳檔案或目錄所佔用的位元組數:



file type 可以取得檔案或目錄的類型,它的回傳值可能是:file、directory、characterSpecial、blockSpecial、fifo、link或是socket。



12.4 檔案名稱及路徑處理

file命令提供了數個與平台無關的檔案路徑操作功能,如果說你想要寫跨平台的程式,這些功能將會非常的管用,因為它們讓你不用在意路徑分隔是斜線、反斜線還是其它。注意!! 接下來說明的file命令都是對字串來操作,換句話說,就算檔案不是真的存在,這些命令同樣可以正常的運作。

□ 取得檔案的副檔名

file extension分析檔案路徑,然後回傳副檔名的部份。



程式的第2行路徑中並沒有包含副檔名,所以程式會輸出空字串。

程式輸出:

.txt

□ 取得檔案的父目錄

file dirname分析檔案路徑,然後回傳目錄的部份。



程式的第一行因為沒有目錄的部份,所以會回傳「.」表示目前的目錄。

程式輸出:

.
/Users

□ 取出檔案的檔名部份

file tail分析檔案路徑中的檔名部份,並回傳檔名部份。



程式輸出:

a.txt

□ 移去檔案的副檔名

file rootname分析檔案路徑,然後回傳移去副檔名後的結果。



程式輸出:

/Users/dai/a

□ 切割檔案路徑

file split切割檔案路徑並以清單的方式回傳切割後的結果。



程式輸出:

/ Users dai a.txt

□ 組合檔案路徑

file join可以用來組合檔案路徑,並回傳組合後的結果。



程式輸出:

/ Users/dai/a.txt

□ 正規化檔案路徑

file normalize會解析檔案路徑中的「..」及「.」符號,並回傳處理後的結果。



程式輸出:

/a/b
/a/b/c

□ 轉換路徑

file nativenam轉換檔案路徑為目前平台相依的格式。



Linux及Mac下的程式輸出:

/Users/dai/a.txt

Windows下的程式輸出:

\Users\dai\a.txt

□ 取得路徑分隔符號

file separator傳回目前平台的路徑分隔符號。



Linux及Mac下的程式輸出:

/

Windows下的程式輸出:

\

12.5 檔案及目錄的屬性處理

接下來要介紹檔案及目錄的屬性檔案。

□ 存取時間屬性

file atime可以用來取得或是設定檔案或目錄的最後存取時間,回傳的時間是由1970/1/1開始算起的秒數。

file mtime可以用來取得或是設定檔案或目錄的最後修改時間,回傳的時間是由1970/1/1開始算起的秒數。



程式第2行中的clock seconds會回傳自1970/1/1到目前的秒數。

□ 存取權限屬性

file attribute可以用來取得或是設定檔案的屬性。如果你要用attribute來取得所有可用的屬性可以這樣做:



在我的Mac系統下它有如下的輸出:

-group staff -owner dai -permissions 00644 -readonly 0 -creator {} -type {} -hidden 0 -rsrclength 0

如果你要設定屬性可以這樣做:



file executable回傳檔案是否有可執行的權限。回傳1表示可執行,否則回傳0。

file readable回傳檔案或目錄是否有讀取的權限。回傳1表示可讀取,否則回傳0。

file writable回傳檔案或目錄是否有寫入的權限。回傳1表示可寫入,否則回傳0。



file owned name回傳檔案是否屬於目前使用者。回傳1表示是,否則回傳0。



□ 存取檔案的狀態

file lstat可以取得檔案的資訊,功能如同lstat系統乎叫。它的語法如下:

file lstat name varName

file stat可以取得檔案的資訊,功能如同stat系統乎叫。它的語法如下:

file stat name varName

這兩個命令都會取得檔案或目錄name的狀態,並把取得的資訊以陣列的型式儲存在varName指定的變數裡。如下是取回的陣列元素:

atime 檔案最後存取的時間。
ctime 檔案狀態最後變更的時間。
dev 檔案系統的裝置代號。
gid 檔案所有群組的ID。
ino i-node編號。
mode 檔案屬性。
mtime 檔案最後修改的時間。
nlink 連結數量。
size 檔案的大小。
type 檔案的類型,和file type一樣。
uid 檔案所有者的ID。

程式範例:



程式輸出:

data(ctime) = 1239428193
data(dev)   = 234881026
data(gid)   = 20
data(ino)   = 192353
data(mode)  = 16877
data(mtime) = 1239428193
data(nlink) = 42
data(size)  = 1428
data(type)  = directory
data(uid)   = 501

12.6 其它檔案處理功能

file channels可以列出已經開啟的檔案通道。它的語法如下:

file channels ?pattern

file channels以清單的方式回傳符合pattern的通道代碼,如果不指定pattern的話會回傳所有的通道代碼。



file system用來分析檔案儲存在哪一種檔案系統下。



在Windows XP下,這個程式應該會輸出:

native NTFS

file volumes以清單的方式列出目前已掛載的檔案系統目錄



在我的Windows下它輸出了:

A:/ C:/ D:/ X:/

Theme Design by devolux.org. Converted by Wordpress To Blogger for WP Blogger Themes. Sponsored by iBlogtoBlog
This template is brought to you by : allblogtools.com | Blogger Templates