Lua_第 21 章 作業系統庫

heyuchang666發表於2016-04-06

第 21 章 作業系統庫 

       作業系統庫包含了檔案管理,系統時鐘等等與作業系統相關資訊。這些函式定義在表(table)os 中。定義該庫時考慮到 Lua 的可移植性,因為 Lua是以 ANSI C 寫成的, 所以只能使用 ANSI 定義的一些標準函式。許多的系統屬性並不包含在 ANSI 定義中, 例如目錄管理,套接字等等。所以在系統庫裡並沒有提供這些功能。另外有一些沒有包含在主體發行版中的 Lua庫提供了作業系統擴充套件屬性的訪問。例如 posix 庫,提供了對POSIX 1 標準的完全支援;在比如 luasocket 庫,提供了網路支援。

       在檔案管理方面作業系統庫就提供了 os.rename 函式(修改檔名)和 os.remove 函 數(刪除檔案)。

 

21.1 Date 和 Time

     time 和 date 兩個函式在 Lua 中實現所有的時鐘查詢功能。函式 time 在沒有引數時 返回當前時鐘的數值。(在許多系統中該數值是當前距離某個特定時間的秒數。)當為函式呼叫附加一個特殊的時間表時,該函式就是返回距該表描述的時間的數值。這樣的時間表有如下的區間:

    

year               a full year
month                  01-12
day                  01-31
hour                  01-31
min                  00-59
sec                  00-59
isdst a boolean, true if daylight saving

前三項是必需的,如果未定義後幾項,預設時間為正午C12:00:00)。如果是在里約熱內盧(格林威治向西三個時區)的一臺 Unix 計算機上(相對時間為 1970 年 1 月 1 日, 00:00:00)執行如下程式碼,其結果將如下。

-- obs: 10800= 3*60*60 (3hours)
print(os.time{year=1970, month=1,day=1, hour=0})
--> 10800
print(os.time{year=1970, month=1,day=1, hour=0, sec=1})
--> 10801
print(os.time{year=1970, month=1,day=1})
--> 54000   (obs: 54000 =10800 + 12*60*60)

函式 data,不管它的名字是什麼,其實是 time 函式的一種"反函式"。它將一個表 示日期和時間的數值,轉換成更高階的表現形式。其第一個引數是一個格式化字串,描述了要返回的時間形式。第二個引數就是時間的數字表示,預設為當前的時間。使用 格式字元"*t",建立一個時間表。例如下面這段程式碼:

temp =os.date("*t", 906000490)

則會產生表

 
{year = 1998,month = 9, day = 16, yday = 259,wday = 4, hour = 23,min = 48, sec = 10, isdst= false}

 不難發現該表中除了使用到了在上述時間表中的區域以外,這個表還提供了星期 (wday,星期天為 1)和一年中的第幾天(yday,一月一日為 1)除了使用 "*t"格式字 符串外,如果使用帶標記(見下表)的特殊字串,os.data 函式會將相應的標記位以時 間資訊進行填充,得到一個包含時間的字串。(這些特殊標記都是以 "%" 和一個字母 的形式出現)如下:

print(os.date("today is %A, in %B"))
--> today isTuesday, in May
print(os.date("%x", 906000490))
--> 09/16/1998

這些時間輸出的字串表示是經過本地化的。所以如果是在巴西(葡萄牙語系),"%B" 得到的就是 "setembro"(譯者按:大概是葡萄牙語九月?),"%x" 得到的就是 "16/09/98"(月日次序不同)。標記的意義和顯示例項總結如下表。例項的時間是在1998年九月 16  日,星期三,23:48:10。返回值為數字形式的還列出了它們的範圍。(都是按照英語系的顯示描述的,也比較簡單,就不煩了)


%a                    abbreviated weekday name (e.g., Wed)
%A                    full weekday name (e.g., Wednesday)
%b                    abbreviated month name (e.g., Sep)
%B                    full month name (e.g., September)
%c                     date and time (e.g., 09/16/98 23:48:10)
%d                           day of the month (16) [01-31]
%H                      hour, using a 24-hour clock (23) [00-23]
%I                       hour, using a 12-hour clock (11) [01-12]
%M                                  minute (48) [00-59]
%m                                  month (09) [01-12]
%p                                either "am" or "pm" (pm)
%S                                  second (10) [00-61]
%w                    weekday (3) [0-6 = Sunday-Saturday]
%x                                  date (e.g., 09/16/98)
%X                                  time (e.g., 23:48:10)
%Y                                     full year (1998)
%y                                 two-digit year (98) [00-99]
%%                                      the character '%'
      事實上如果不使用任何引數就呼叫 date,就是以%c 的形式輸出。這樣就是得到經過格式化的完整時間資訊。還要注意%x、%X 和%c由所在地區和計算機系統的改變會發生變化。如果該字串要確定下來(例如確定為 mm/dd/yyyy),可以使用明確的字串 格式方式(例如"%m/%d/%Y")。

      函式 os.clock 返回執行該程式 CPU 花去的時鐘秒數。該函式常用來測試一段程式碼。

local x = os.clock()
local s = 0
for i=1,100000 do s = s + i end
print(string.format("elapsed time: %.2f\n", os.clock() - x))


21.2 其它的系統呼叫

函式 os.exit 終止一個程式的執行。函式 os.getenv 得到"環境變數"的值。以"變數 名"作為引數,返回該變數值的字串:

print(os.getenv("HOME"))    --> /home/lua

如果沒有該環境變數則返回 nil。函式 os.execute 執行一個系統命令(和 C 中的 system 函式等價 )。該函式獲 取一個命令 字串,返 回一個錯誤 程式碼。例如 在 Unix 和 DOS-Windows  系統裡都可以執行如下程式碼建立一個新目錄:

function createDir (dirname)
       os.execute("mkdir " .. dirname)
end

       os.execute 函式較為強大,同時也更加倚賴於計算機系統。函式 os.setlocale設定 Lua 程式所使用的區域(locale)。區域定義的變化對於文化和語言是相當敏感的。setlocale 有兩個字串引數:區域名和特性(category,用來表示區域的各項特性)。在區域中包 含六項特性:"collate"(排序)控制字元的排列順序;"ctype"controls the types of individualcharacters (e.g., what is a letter) and the conversion between lower and upper cases; "monetary"(貨幣)對 Lua程式沒有影響;"numeric"(數字)控制數字的格式;"time"控制時間的格式(也就是 os.date 函式);和"all"包含以上所以特性。函式預設的特性 就是"all",所以如果你只包含地域名就呼叫函式setlocale 那麼所有的特性都會被改變為 新的區域特性。如果執行成功函式返回地域名,否則返回 nil(通常因為系統不支援給定 的區域)。

print(os.setlocale("ISO-8859-1", "collate")) --> ISO-8859-1

關於"numeric"特性有一點難處理的地方。儘管葡萄牙語和其它的一些拉丁文語言使用逗號代替點號來表示十進位制數,但是區域設定並不會改變Lua劃分數字的方式。(除了其它一些原因之外,由於print(3,4)還有其它的函式意義。)因此設定之後得到的系統也許既不能識別帶逗號的數值,又不能理解帶點號的數值:

-- 設定區域為葡萄牙語系巴西 
print(os.setlocale('pt_BR')) --> pt_BR 
print(3,4)        --> 3   4
print(3.4)        --> stdin:1: malformed numbernear `3.4'

The category "numeric" is a little tricky. Although Portuguese and other Latin languages usea comma instead of a point to represent decimal numbers, the locale does not change thewaythat Lua parses numbers (among other reasonsbecause expressions like print(3,4) alreadyhave a meaning in Lua). Therefore,you may end with a system that cannot recognize numbers withcommas,but cannot understand numberswithpointseither:

 

<pre name="code" class="csharp">-- set locale forPortuguese-Brazil
print(os.setlocale('pt_BR'))                  --> pt_BR 
print(3,4)   --> 3  4
print(3.4)        --> stdin:1: malformed numbernear '3.4'


相關文章