Lua的標準庫能與C語言的API直接實現(xiàn)
- 基礎函數(shù)庫
- 協(xié)程庫
- string庫
- table庫
- math庫
- io庫
- 操作系統(tǒng)庫
- debug庫
http://cloudwu.github.io/lua53doc/manual.html#6.4
string庫
字符串處理庫提供了字符串處理的通用函數(shù)镰禾,如字符串查找衍菱、子串垒棋、模式匹配等吱晒。當在Lua中對字符串作索引時,第一個字符從1開始計算质涛,而不是C語言中的0。索引可以是負數(shù),表示從字符串末尾反向解析泌绣。也就是說,最后一個字符在-1位置上预厌。
字符串庫中的所有函數(shù)都在表string
中阿迈,它還將其設置為字符串元表的__index
域。因此轧叽,可以以面向對象的方式使用字符串函數(shù)苗沧。
- Lua中沒有字符串類型刊棕,Lua的
string
類型表示字符序列。 -
string
字符序列中字符采用8位編碼待逞,可存放任意二進制數(shù)據(jù)甥角。 -
string
是不可變的值,修改后會返回新string
识樱,原有string
保持不變嗤无。 -
string
字面值采用單引號或雙引號包裹 -
string
使用[[
和]]
界定字符串 - Lua提供運行時數(shù)字和字符的自動轉換
- 長度操作符
#
可獲取字符串的長度即字符個數(shù)
原始Lua解釋器操作字符串的能力有限,只能創(chuàng)建字符串常量怜庸、連接字符串当犯、獲取字符串長度。無法提取子串或檢索字符串內容割疾。Lua中字符串操作能力源于string
庫嚎卫。
基礎字符串函數(shù)
-
string.len(str)
獲取字符串的長度
local str = "hi lua\t, what\n lua\000"
print(string.len(str), #str) --19 19
-
string.rep(str, n)
字符串重復n次并拼接返回
local str = "-"
local result = string.rep(str,10)
print(result)-- ----------
-
string.lower(str)
字符串轉小寫
local str = "String.Lower"
local result = string.lower(str)
print(result) -- string.lower
local result = string.upper(str)
print(result) -- STRING.LOWER
local result = string.reverse(str)
print(result) -- rewoL.gnirtS
-
string.sub(str, begin[, end])
截取字符串
local str = "[this is a island]"
local result = string.sub(str, 2, -2)
print(str, result)
-- [this is a island]
-- this is a island
對字符串數(shù)組排序且不區(qū)分大小寫
local arr = {"Alice", "Mary", "carl", "Fifi", "jay"}
table.sort(arr, function(x,y)
return string.lower(x) < string.lower(y)
end)
print(table.concat(arr,",")) --Alice,carl,Fifi,jay,Mary
-
string.char(...)
將數(shù)字編碼轉換為字符串
print(string.char(97, 100, 101)) --ade
-
string.byte(...)
將字符轉換為數(shù)字
print(string.byte("abc", 3)) --99
print(string.byte("abcde", 3, 5)) -- 99 100 101
-
string.format(format, ...)
格式化字符串
print(string.format("pi = %.4f", math.pi)) -- pi = 3.1416
print(string.format(
"%4d-%02d-%02d %02d:%02d:%02d",
os.date("%Y"),
os.date("%m"),
os.date("%d"),
os.date("%H"),
os.date("%M"),
os.date("%S")
))
-- 2018-12-07 23:45:02
模式匹配函數(shù)
Lua中的匹配模式直接用常規(guī)的字符串來描述,用于模式匹配函數(shù)string.find
杈曲、string.match
驰凛、string.gmatch
、string.gsub
担扑。
Lua即沒有使用POSIX也沒有使用Perl正則表達式來進行模式匹配恰响,其原因主要是考慮到Lua的大小。
Lua中的模式匹配字符串涌献,用來表示一個字符集合胚宦,可組合使用。
-
x
表示字符x
自身 -
.
點表示任何字符 -
%a
表示任何字母 -
%c
表示任何控制字符 -
%d
表示任何數(shù)字 -
%g
表示任何除空白符外的可打印字符 -
%l
表示所有小寫字母 -
%p
表示所有標點符號 -
%s
表示所有空白字符 -
%u
表示所有大寫字母 -
%w
表示所有字母及數(shù)字 -
%x
表示所有16進制數(shù)字符號 -
%X
X表示任意非字母或數(shù)字的字符
所有單個字母表示的類別燕垃,若將字母改為大寫均表示對應的補集枢劝。如何定義字母、空格卜壕、其他字符組取決于當前的區(qū)域設置您旁。
-
string.find(str, pattern, [, init [, plain]])
用于在一個給定的目標字符串中搜索一個模式,匹配與自己完全相同的拷貝轴捎。當匹配成功后會返回兩個值:匹配到的起始索引和結尾索引鹤盒,若沒有匹配到則返回nil
。
參數(shù)1:str
表示給定的目標字符串
參數(shù)2:pattern
表示待匹配的字符串
參數(shù)3:init
表示從哪里開始搜索侦副,默認值為1侦锯,可為負數(shù)。
參數(shù)4:plain
為true
表示關閉模式匹配機制秦驯,此時函數(shù)僅做直接的查找字符子串操作尺碰,但pattern
中沒有字符被看作魔法字符。注意如果給定了plain
則必須填寫init
。
local str = "this is a island"
local x,y = string.find(str, "is")
print(x, y) -- 3 4
在字符串中所有換行符的位置創(chuàng)建表
local str = "this\nis\na\nisland"
local tbl = {}
local i = 0
while true do
i = string.find(str, "\n", i+1)
if i==nil then
break
end
tbl[#tbl + 1] = i
end
print(table.concat(tbl,","))-- 5,8,10
local pair = "name = Anna"
local start,stop,key,val = string.find(pair, "(%a+)%s*=%s*(%a+)")
print(start, stop ,key, val)-- 1 11 name Anna
-
string.match(str, pattern, [, init])
在目標字符串str中找到第一個能用pattern
匹配到的部分亲桥,若找到則match
返回其中捕獲的字符串洛心,否則返回nil
。若pattern
中未指定捕獲則返回整個pattern
捕獲到的字符串两曼≡砀剩可選參數(shù)init
表示從哪里開始搜索默認為1可為負數(shù)。
local str = "today is 2018-12-08"
local year,month,day = string.match(str, "(%d+)-(%d+)-(%d+)")
print(year, month, day)--2018 12 08
-
string.gsub(str, pattern, replacement, [, n])
全局(global)替換子字符串
參數(shù):
參數(shù)1:str
源字符串
參數(shù)2:pattern
匹配模式
參數(shù)3:將匹配模式pattern
匹配到的字符串替換為replacement
參數(shù)4:n
可選表示只看源字符串的前n
個字符
返回值
返回值1:替換后的字符串
返回值2:替換的次數(shù)
function trim(str)
return (string.gsub(str, "^%s*(.-)%s*$", "%1"))
end
print(trim("\t jun chow ")); -- jun chow
math庫
-- 獲取圓周率
print(math.pi) -- 3.1415926535898
-- 獲取Lua可表示最大數(shù)字
print(math.huge) -- inf
-- 設置隨機種子悼凑,在使用math.random函數(shù)前必須先設置偿枕。
print(math.randomseed(os.time()))
-- 生成0到1之間的隨機數(shù)
print(math.random()) -- 0.001251220703125
-- 生成1到100之間的隨機數(shù)
print(math.random(100)) -- 57
-- 生成6位隨機數(shù)
print(math.random(100000, 999999)) -- 273968
table庫
Lua中table
表具有以下特性
-
table
表是一個關聯(lián)數(shù)組,數(shù)組的索引可以是數(shù)字或字符串户辫。 -
table
表默認初始索引以1開始 -
table
表的變量是一個地址引用渐夸,對table
的操作不會產(chǎn)生數(shù)據(jù)影響。 -
table
表可自動擴容
table
庫由輔助函數(shù)構成渔欢,默認會將table
作為數(shù)組來操作墓塌。
- table.concat(table, separator, start, end)
- table.insert(table, position, value)
- table.remove(table, position)
- table.sort(table, compare)
table.insert(table, position, value)
用于將元素value
插入到數(shù)組table
的指定位置position
,會移動后續(xù)元素以騰出空間奥额。其中位置參數(shù)position
為可選苫幢,默認為數(shù)組末尾。
local tbl = {"alpha", "beta", "gamma"}
table.insert(tbl, "delta")
table.insert(tbl, "epsilon")
table.insert(tbl, "zeta")
print(table.concat(tbl, ","))-- alpha,beta,gamma,delta,epsilon,zeta
local tbl = {1, 2, 3}
table.insert(tbl, 1, 10)
for i,v in ipairs(tbl) do
print(i,v)-- 10 1 2 3
end
table.remove(table, position)
刪除并返回table
數(shù)組指定位置position
上的元素垫挨,并將該位置之后的所有元素前移韩肝,以填補空隙。如果在調用此函數(shù)時不指定位置position
參數(shù)九榔,則會刪除數(shù)組的最后一個元素哀峻。
local tbl = {"alpha", "beta", "gamma"}
table.remove(tbl)
print(table.concat(tbl, ","))-- alpha,beta
table.concat(table, separator, start, end)
table.concat
接收一個字符串數(shù)組并返回字符串連接后的結果。列出參數(shù)中指定數(shù)組table
從開始位置start
到結束位置end
的所有元素哲泊,元素間以指定分隔符separator
隔開剩蟀。除了table
外,其他參數(shù)都不是必須的切威,分隔符separator
默認是空字符育特,開始位置start
默認為1,結束位置end
默認為數(shù)組的長度先朦。
local tbl = {"alpha", "beta", "gamma"}
print(table.concat(tbl)) --alphabetagamma
print(table.concat(tbl,","))--alpha,beta,gamma
print(table.concat(tbl, 2, 3))-- gamma
擴展table.concat
使其能處理嵌套的字符串數(shù)組
function concat(tbl)
if type(tbl)~="table" then
return tbl
end
local result = {}
for i=1,#tbl do
result[i] = concat(tbl[i])
end
return table.concat(result)
end
-- test
local arr = {
{"a", {" nice "}},
"and",
{{" long "}, "list"}
}
print(concat(arr))--a nice and long list
table.sort(table, compare)
table.sort()
函數(shù)對給定的table
進行升序排序且预,其中compare
為可選參數(shù),可以是一個外部函數(shù)用來自定義排序標準烙无。排序函數(shù)的標準是接收兩個參數(shù)并返回一個布爾型的值,若布爾值為true
則表示升序否則則為降序遍尺。
在table
中索引是一個無序的集合截酷,若要對其進行排序則必 須將其復制到一個數(shù)組中,然后對數(shù)組元素進行排序乾戏。值得注意的迂苛,對于Lua而言三热,數(shù)組也是無序的,它們的本質都是table
三幻。
-- 對鍵名進行排序的迭代器
function pairsByKeys(tbl, fn)
-- 獲取鍵名
local result = {}
for k,v in pairs(tbl) do
result[#result + 1] = k
end
-- 對鍵名進行排序
table.sort(result, fn)
-- 迭代器
local i = 0 --迭代器變量
return function()
i = i + 1
return result[i], tbl[result[i]]
end
end
-- test
local fns = {
set=10,
get=100,
count=29
}
for index,value in pairsByKeys(fns) do
print(index, value)
end
--[[
count 29
get 100
set 10
--]]
操作系統(tǒng)庫
Lua操作系統(tǒng)庫函數(shù)就漾,包含了文件管理、系統(tǒng)時鐘等于操作系統(tǒng)相關信息念搬,這些函數(shù)定義在表os
中抑堡。
日期時間
- os.clock() 返回程序使用CPU時間的近似值
- os.time([table]) 默認獲取當前時間戳,可指定日期時間的
table
參數(shù)朗徊。 - os.date([format [, time]]) 格式化時間戳為可讀時間首妖,
time
為可選默認省略時為當前時間戳。 - os.difftime(ts2, ts1) 返回時間戳ts1到時間戳ts2相差的秒數(shù)
os.clock()
-
os.clock()
返回程序使用CPU時間的近似值
print(os.clock(), string.format("%.2f", os.clock())) -- 0.0 0.00
計算程序執(zhí)行消耗的CPU秒數(shù)
local clock_begin = os.clock()
local sum = 0
for i=1, 1000000 do
sum = sum + i
end
local clock_end = os.clock()
print(string.format("elapsed seconds is %.2f\n", clock_end - clock_begin))
-- elapsed seconds is 0.02
-
os.clock()
的實現(xiàn)是調用C語言的函數(shù)庫爷恳,其中CLOCKS_PER_SEC
值在不同平臺有著不同定義有缆。
static int os_clock(lua_State *L){
lua_pushnumber(L, (lua_Number))/(lua_Number)CLOCKS_PER_SEC;
return 1;
}
- 可使用
socket
庫的socket.gettime()
替代os.clock()
require "socket"
local time = socket.gettime()
- 要注意函數(shù)的溢出問題,程序運行時間太長的話温亲,使用
clock
有可能返回負數(shù)棚壁。
os.time([table])
按table
內容返回一個數(shù)字時間值,若無參數(shù)則返回當前時間table
的字段栈虚。返回一個指定時間點的UNIX時間戳袖外,若無參數(shù)調用則返回當前時間點的UNIX時間戳。
-- 獲取當前UNIX的10位秒級時間戳
print(os.time()) -- 1544030239
-- 獲取指定日期時間的時間戳
os.time({year=2018, month=06, day=05, hour=12, min=23, sec=45, isdst=true})
os.date([format [, time]])
os.date
是os.time
的反函數(shù)节芥,將一個UNIX時間戳裝換成可讀的字符串形式在刺。若省略第二個參數(shù)time
則默認返回當前時間點的日期。返回按format
格式化后的日期头镊、時間的字符串或表蚣驼。若設置time
參數(shù),則按time
指定的時間格式進行格式化相艇,否則按當前時間格式化颖杏。
print(os.date()) -- 12/06/18 01:21:35
print(os.date("%Y-%m-%d %H:%M:%S")) -- 2018-12-06 01:22:06
參數(shù)說明:
format
參數(shù)為空則按當前系統(tǒng)的設置返回格式化后的字符串,為了生成日期的table
可使用格式字符串*t
坛芽。
-
!
按格林威治時間進行格式化 -
*t
返回帶4位年留储、1-12的月份,1-31的日期咙轩、0-23的小時數(shù)获讳、0-59分鐘數(shù)、 0-61秒數(shù)活喊、1-7星期數(shù)
local tbl = os.date("*t", os.time())
for k,v in pairs(tbl) do
print(k, v)
end
--[[
yday 340
year 2018
sec 21
day 6
month 12
hour 1
min 25
isdst false
wday 5
--]]
os.date
會將日期格式化為一個字符串丐膝,此字符串是傳入格式字符串的副本,其中某些特殊表被替換成時間和日期信息,所有標記都以%
開頭帅矗,并伴隨一個字符偎肃。
%a 一個星期中天數(shù)的簡寫
%A 一個星期找那個天數(shù)的全稱
%b 月份簡寫
%B 月份全稱
%c 日期和時間
%d 一個月中的第幾天
%H 24小時制中的小時數(shù)
% I 12小時制中的小時數(shù)
%j 一年中的第幾天
%M 分鐘數(shù)
%m 月份數(shù)
%P 上午am或下午pm
%S 秒數(shù)
%w 一星期中的第幾天
%W 一年中第幾個星期
%x 日期
%X 時間
%y 兩位數(shù)的年份
%Y 完整的年份
%% 字符串%
時間戳轉為日期
function ts2date(ts)
local tbl = {}
local date = string.format(os.date("%x", ts))
local arr = string.split(date, "/")
tbl.YEAR = checkint(arr[3])
tbl.MONTH = checkint(arr[1])
tbl.DAY = checkint(arr[2])
return tbl
end
計算時間戳間隔天數(shù)
function diff_days(mints, maxts)
local temp = nil
if maxts<mints then
temp = mints
mints = maxts
maxts = temp
end
return checkint(maxts/86400) - checkint(mints/86400)
end
os.difftime(t2, t1)
返回時間戳ts1到ts2相差的秒數(shù),可用于計算代碼的執(zhí)行時長浑此。
local ts1 = os.time()
for i=0,10000000 do
math.random()
end
local ts2 = os.time()
print(os.difftime(ts2, ts1)) --1.0
系統(tǒng)調用
os.execute([command])
系統(tǒng)級的函數(shù)調用os.execute
相當于·C語言中的system()
累颂,函數(shù)有缺省的參數(shù)command
,函數(shù)是解析command
后在通過系統(tǒng)來調用解析的結果凛俱,返回一個依賴于操作系統(tǒng)的狀態(tài)碼紊馏。當參數(shù)缺省時,若操作系統(tǒng)可以調用解析參數(shù)則返回非0的數(shù)否則返回0最冰。
local ret = os.execute()
if ret ~= 0 then
os.execute("color 02") -- 將命令行的顏色由白色修改為綠色
os.execute("copy test.lua test.lua.bak")
os.execute("pause")
end
os.exit(code)
按任意鍵繼續(xù)...瘦棋,相當于C語言中的exit
函數(shù),終止主程序暖哨,code
為返回值赌朋。
-- 結束程序并返回狀態(tài)碼,0代表成功篇裁。
print("run then exit")
os.exit(0)
print("can't output")
-- run then exit
os.setlocale(locale[, category])
設置程序本地配置沛慢,函數(shù)返回最新配置,若失敗則返回nil
达布。
os.setlocale("zh_CN.utf8", "time")
print(os.date())
local
指定當前配置名稱的字符串
- "" 空字符串表示當前配置被視為本地配置
- "c" 表示當前配置被視為標準C配置
- nil 返回category設置的配置名稱的當前值
category
描述待更改的配置名稱
- all
- collate
- ctype
- monetary
- numeric
- time
os.getenv(varname)
返回當前進程的環(huán)境變量varname
(不區(qū)分大小寫)的值团甲,若變量沒有定義時返回為nil
。
-- 獲取操作系統(tǒng)名稱
print(os.getenv("OS")) -- Windows_NT
-- 獲取系統(tǒng)用戶名
print(os.getenv("USERNAME")) -- jc
-- 獲取當前登錄服務器名稱
print(os.getenv("LOGONSERVER")) -- \\WIN10-JC
-- 獲取用戶域名
print(os.getenv("USERDOMAIN")) -- WIN10-JC
-- 獲取計算機名稱
print(os.getenv("COMPUTERNAME")) -- WIN10-JC
-- 獲取處理器cpu數(shù)量
print(os.getenv("NUMBER_OF_PROCESSORS")) -- 8
-- 獲取處理器CPU修訂號
print(os.getenv("PROCESSOR_REVISION")) -- 3c03
-- 獲取處理器CPU的型號
print(os.getenv("PROCESSOR_LEVEL")) -- 6
-- 獲取處理器CPU的架構
print(os.getenv("PROCESSOR_ARCHITECTURE")) -- AMD64
-- 獲取處理器CPU標識
print(os.getenv("PROCESSOR_IDENTIFIER")) -- Intel64 Family 6 Model 60 Stepping 3, GenuineIntel
-- 獲取命令行解釋器可執(zhí)行程序的完整路徑
print(os.getenv("COMSPEC")) -- C:\WINDOWS\system32\cmd.exe
print(os.getenv("ComSpec")) -- C:\WINDOWS\system32\cmd.exe
-- 獲取系統(tǒng)支持的文件擴展名
print(os.getenv("PATHEXT")) -- .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC
-- 獲取用戶主目錄的本地驅動器(本地盤符)
print(os.getenv("HOMEDRIVE")) -- C:
-- 獲取系統(tǒng)根目錄
print(os.getenv("SystemRoot")) -- C:\WINDOWS
-- 獲取用戶配置文件路徑
print(os.getenv("ALLUSERSPROFILE")) -- C:\ProgramData
-- 獲取用戶主目錄完整路徑
print(os.getenv("HOMEPATH")) -- \Users\jc
-- 獲取系統(tǒng)臨時目錄完整路徑
print(os.getenv("TEMP")) -- C:\Users\jc\AppData\Local\Temp
print(os.getenv("ProgramFiles")) -- C:\Program Files
print(os.getenv("APPDATA")) -- C:\Users\jc\AppData\Roaming
print(os.getenv("CommonProgramFiles")) -- C:\Program Files\Common Files
os.tmpname()
返回臨時文件名稱黍聂,自動產(chǎn)生臨時文件并返回文件名如/tmp/sc9k
躺苦,如果要使用,必須手動打開文件产还,最后不使用時必須手動刪除匹厘。io.tmpfile()
產(chǎn)生的臨時文件程序結束后會自動刪除。
print(os.tmpname()) --\sc9k.
os.rename(oldname, newname)
更改文件或目錄名脐区,若函數(shù)調用失敗則返回nil
和錯誤信息愈诚。
os.remove(filename)
刪除文件或空白目錄,若函數(shù)調用失敗則返回nil
和錯誤信息牛隅。
io庫
Lua I/O庫用于讀取和處理文件炕柔,提供兩套不同風格的文件處理接口(模型),分為簡單模式(和C語言一樣)和完全模式媒佣。
- 簡單模式(simple model)
使用隱式的文件句柄匕累,假設有一個當前當前輸入文件和一個當前輸出文件,提供默認輸入文件和輸出文件的操作默伍。擁有一個當前輸入文件和一個當前輸出文件哩罪,提供針對這些文件相關的操作授霸。
使用隱含的文件描述符,有操作設置默認的輸入文件和輸出文件际插。
- 完全模式(complete model)
使用顯式文件句柄,使用外部的文件句柄來實現(xiàn)显设,以面向對象的方式框弛,將所有文件操作定義為文件句柄的方法。
明確的操作描述符
使用明確的文件描述符時捕捂,所有操作由表io
提供瑟枫,使之能夠在同一時間內處理多個文件,功能相當相似的隱式文件操作符指攒。
-- 使用明確的文件描述符能夠在同一時間處理多個文件
file:function
-- eg
file = io.open("test.lua", "r")
print(file:read())
file:close()
file = io.open("test.lua", "a")
file:write("---------------------")
file:close()
io.open
返回文件操作符和操作方法慷妙,表io
提供3個與定義的文件描述符:
io.stderr 標準錯誤輸出
io.stdin 標準輸入
io.stdout 標準輸出
io
表調用方式
表io中提供三個和C語言中含義相同的預定義文件句柄:io.stdin
、io.stdout
允悦、io.stderr
膝擂。IO庫永遠不會關閉這些文件。
使用io
表隙弛,io.open()
將返回指定文件的描述架馋,且所有的操作將圍繞這個文件描述io表同樣提供3中預定義的文件描述:io.stdin
、io.stdout
全闷、io.stderr
叉寂。
- 文件句柄直接調用方式
使用file:xxx()
函數(shù)方式進行操作,其中file
為ioi.open()
返回的文件句柄总珠,多數(shù)io
函數(shù)調用失敗時返回nil
和錯誤信息屏鳍。
除非另有說明,IO函數(shù)在出錯時都返回nil
局服,第二個返回值為錯誤消息钓瞭,第三個返回值為系統(tǒng)相關的錯誤代碼。成功時返回與nil
不同的值腌逢。
簡單模式
簡單模式的所有操作都作用于兩個當前文件降淮,I/O庫將當前輸入文件初始化為進程標準輸入stdin
,將當前輸出文件初始化為進程標準輸出stdout
搏讶。
I/O庫會將標準輸入輸出作為其缺省的輸入文件和輸出文件佳鳖,可通過io.input(filename)
和io.output(filename)
來改變當前輸入輸出文件。
使用io.write()
和io.read()
從標準輸入stdin
讀取輸出到標準輸出stdout
媒惕,在執(zhí)行io.read()
操作時系吩,會從標準輸入中讀取一行。使用io.input()
和io.output()
改變當前文件妒蔚。
io.input(filename)
以只讀模式打開指定文件穿挨,并將其設定為當前輸入文件月弛,除非再次調用io.input()
,否則所有的輸入都將來源于這個文件科盛。
io.input([file])
相當于io.input
帽衙,但操作在默認輸出文件上。使用文件名調用時贞绵,以文本模式來打開該名稱的文件厉萝,并將文件句柄設置為默認輸入文件。若使用文件句柄去調用它榨崩,則簡單地將句柄設置為默認輸入文件谴垫。若調用時不傳入?yún)?shù)則返回當前的默認輸出文件。在出錯的情況下母蛛,函數(shù)拋出錯誤而非返回錯誤碼翩剪。
io.output(filename)
在輸出方面,io.output()
也可以完成類似的工作彩郊。
io.output([file])
使用文件名稱調用時前弯,以文本模式打開該名稱的文件,并將文件句柄設置為默認輸出文件焦辅。若使用文件句柄去調用它博杖,就簡單地將該句柄設置為默認輸出和文件。若調用時不傳入?yún)?shù)則返回當前的默認輸出文件筷登。
io.read()
io.read(...)
# 相當于
io.input():read
按指定的格式讀取一個文件剃根,按每個格式函數(shù)將返回一個字符串或數(shù)字,若不能正確地讀取將返回nil
前方,若沒有指定格式將指默認按行方式進行讀取狈醉。
讀取格式
-
*a
從當前位置讀取整個文件,若為文件結尾EOF
則返回空字符串惠险。
io.read("*all")
讀取當前輸入文件的所有內容苗傅,以當前位置作為開始。若當前位置處于文件末尾或文件為空則返回空字符串班巩。由于Lua可以高效地處理長字符串渣慕,因此在Lua中可先將數(shù)據(jù)從文件中完整讀出之后在通過字符串庫提供的函數(shù)進行各種處理。
-
*l
默認選項抱慌,讀取下一行的內容逊桦,若為文件結尾EOF
則返回nil
。
io.read("*line")
-- eg
for count = 1, math.huge do
local line = io.read("*line") -- 缺省值為 *line
if line == nil then
break
end
io.write(string.format("%6d", count), line, "\n")
end
-- 若為了迭代文件中所有行可使用 io.lines 抑进,以迭代器的形式訪問文件中的每一行數(shù)據(jù)强经。
local lines = {}
-- 通過迭代器訪問每行數(shù)據(jù)
for line in io.lines() do
lines[#lines+1] = line
end
-- 使用Lua標準庫table進行排序
table.sort(lines)
for _,l in ipairs(lines) do
io.write(l, "\n")
end
返回當前文件的下一行但不包含換行符,當?shù)竭_文件末尾時則返回nil
寺渗。
-
number
讀取指定字節(jié)數(shù)的字符匿情,若為文件結尾EOF
則返回nil
兰迫,若number為0則返回空字符串。
io.read("*number")
-- eg:讀取注釋中的數(shù)字
while true do
local n1,n2,n3 = io.read("*number", "*number", "*number")
if not n1 then
break
end
print(math.max(n1,n2,n3))
end
從當前輸入文件中讀取一個數(shù)字炬称,此時read
將直接返回一個數(shù)字而非字符串汁果。*number
選項會忽略數(shù)字前面所有的空格,且能處理像-3
玲躯、+5.2
這樣的數(shù)字格式须鼎。若當前讀取的數(shù)據(jù)不合法則返回nil
。調用時可指定多個選項府蔗,函數(shù)會根據(jù)每個選項參數(shù)返回相應的內容。
-
*n
讀取一個數(shù)字并返回它
-- 從輸入文件中最多讀取n個字符汞窗,若讀取不到任何字符則返回 nil姓赤,否則返回讀取到的字符串。
io.read(<num>)
-- eg
while true do
local block = io.read(2^13)
if not block then
break
end
io.write(block)
end
-- 特殊情況仲吏,用于檢查是否到達文件末尾不铆,若尚未到達則返回空字符串否則返回 nil。
io.read(0)
io.write(...)
-- 將所有參數(shù)順序的寫入到當前輸出文件中
io.write(...)
-- 相當于
io.output():write
-- eg:獲取任意數(shù)目的字符串參數(shù)并將其寫入當前標準輸出中
local t = io.write("sin(3)=", math.sin(3), "\n")
print("hello", "lua")
io.write
與print
不同之處在于裹唆,io.write
不附加任何額外的字符到輸出中誓斥,例如制表符、換行符等许帐。io.write
是使用當前輸出文件而print
始終使用標準輸出劳坑。print
會自動調用參數(shù)的tostring
方法,所以可以顯示出表成畦、函數(shù)和nil
距芬。
io.open(filename [,mode])
按指定模式mode
打開一個文件,成功則返回新的文件句柄循帐,失敗則返回nil
和錯誤信息框仔。
文件模式
- r 默認選項,只讀模式拄养,對已存在的文件的默認打開模式离斩。
- w 可寫模式,允許修改已存在的文件和創(chuàng)建新文件且不可讀取瘪匿。
- a 追加模式跛梗,對于已存在的文件允許追加新內容,但不允許修改原來內容柿顶,同時也可以創(chuàng)建新文件茄袖。
- r+ 更新模式,之前數(shù)據(jù)將被保存嘁锯。讀寫模式宪祥,打開已存在的文件聂薪。
- w+ 更新模式,之前數(shù)據(jù)將被清除蝗羊。若文件已存在則刪除文件中的數(shù)據(jù)藏澳,若文件不存在則創(chuàng)建文件,并以讀寫模式打開耀找。
- a+ 添加更新模式翔悠,之前數(shù)據(jù)將被保存,僅允許在文件末尾進行添加野芒。以可讀的追加模式打開已存在的文件蓄愁,若文件不存在則新建文件。
- b 某些系統(tǒng)支持二進制方式
-- 讀取指定文件
function getFile(filename)
local file = assert(io.open(filename, "r"))
local string = file:read("*all")
file:close()
return string
end
-- 按行方式讀取文件內容
function getFileLine(filename)
local BUFSIZE = 84012
local file = assert(io.open(filename, "r"))
local lines,rest = file:read(BUFSIZE, "*line")
file:close()
return lines,rest
end
-- 以字符串方式寫入文件
function writeFile(filename, string)
local file = assert(io.open(filename, "w"))
file:write(string)
file:close()
end
-- 控制臺寫入字符串到文件
function writeConoleToFile(filename)
local file = assert(io.open(filename, "w"))
local string = io.read()
file:write(string)
file:close()
ene
io.popen([prog[, mode]])
開始程序prog
與額外的進程狞悲,并返回用于prog
的文件句柄撮抓,并不支持所有的系統(tǒng)平臺。
使用一個分離進程開啟程序program
摇锋,返回的文件句柄可用于從這個程序中讀取數(shù)據(jù)(mode=r
)或是向程序寫入輸入(mode=w
)丹拯。
io.close(file)
io.close([file])
# 相當于
file:close()
關閉默認的輸出文件,當文件句柄被垃圾收集后荸恕,文件將自動關閉乖酬,句柄將變?yōu)橐粋€不可預知的值。
io.tmpfile()
返回一個臨時文件句柄融求,該文件以更新模式打開咬像,程序結束時自動刪除。
io.type(obj)
檢測obj
是否為一個可用的文件句柄双肤,若obj
是一個打開的文件句柄則返回字符串file
施掏,若obj
是一個關閉的文件句柄則返回字符串close file
。若obj
不是句柄則返回nil
茅糜。
返回值
-
file
為一個打開的文件句柄 -
close file
為一個已關閉的文件句柄 -
nil
表示obj
不是一個文件句柄
io.flush()
io.flush()
# 相當于
file:flush()
向文件寫入緩沖中的所有數(shù)據(jù)七芭,輸出所有緩沖區(qū)中的內容到默認輸出文件。
io.lines(optional filename)
io.lines([filename])
提供一個循環(huán)迭代器以遍歷文件蔑赘,若指定文件名則當遍歷結束后將自動關閉該文件狸驳,若使用默認文件則遍歷結束后不會自動關閉文件。
打開指定的文件filename
為讀模式并返回一個迭代函數(shù)缩赛,每次調用將獲取文件中的一行內容耙箍,當?shù)竭_文件結尾時,將返回nil
并自動關閉文件酥馍。
若不帶參數(shù)時辩昆,io.lines()
相當于io.input():lines()
,表示讀取默認輸入設備的內容但結束時不關閉文件旨袒。
返回一個迭代函數(shù)汁针,每次調用將獲得文件中的一行內容术辐,當?shù)竭_文件結尾時將返回nil,但不關閉文件施无。
for line in io.lines("main.lua") do
print(line)
end
debug庫
Lua本身并未內置調試器辉词,提供了debug
庫用于提供創(chuàng)建自定義調試器的功能。出于性能考慮猾骡,調用基本功能的正式接口都是通過 C API提供瑞躺,在Lua中訪問debug
庫的一種方式是通過Lua代碼直接訪問。與其他庫不同的debug
庫很多功能都會影響性能兴想。其次幢哨,它打破了Lua中一些顛覆不破的真理,如在一個局部變量的作用域之外不能訪問嫂便。
debug
庫中的一種重要的思想是棧級別(stack level)嘱么,一個棧級別就是一個指向在當前時刻正在活動的特殊函數(shù)的數(shù)字。也就是說顽悼,這個函數(shù)正在被調用但還沒有返回。調用debug
庫的函數(shù)級別為1几迄,調用它的函數(shù)級別為2蔚龙,以此類推。
Lua的調試庫包含兩種函數(shù):自省函數(shù)(introspective functions)和鉤子(hooks)映胁。自省函數(shù)可用來監(jiān)視一個正在運行的程序的信息木羹,如活動函數(shù)的棧、當前的執(zhí)行行解孙、局部變量值和名稱等坑填。鉤子可以跟蹤程序的運行。自省函數(shù)主要是debug.getinfo
弛姜。
自省函數(shù)
- debug.getinfo([thread,]func[,what]) 返回一個函數(shù)的信息表
- debug.traceback([thread,][message[, level]]) 獲取調用棧的回溯信息
debug.getinfo([thread,]func[,what])
debug.getinfo
參數(shù)
-
func
可直接傳入函數(shù)脐瑰,也可傳入一個數(shù)值,此數(shù)值表示函數(shù)(運行在指定線程)的調用棧深度廷臼,0表示getinfo
自己苍在,1表示調用getinfo
的函數(shù),以此類推一般是2荠商。若此數(shù)值大于活動函數(shù)的深度返回nil
寂恬。 -
what
函數(shù)類型,若func
是一個普通的Lua函數(shù)則為Lua
莱没,若func
是一個C函數(shù)則為C
初肉,若是Lua主程序塊(chunk)部分則為main
。
debug.getinfo
返回值是一個table
包含以下字段
-
source
函數(shù)定義的位置饰躲,若函數(shù)時通過loadstring
在一個字符串中定義的牙咏,那么source
就是這個字符串臼隔。若函數(shù)是在一個文件中定義的,那么source
就是這個文件名加前綴@
眠寿。 -
short_src
是source
的短版本躬翁,最多60個字符,可用于錯誤信息匯總盯拱。 -
linedefined
該函數(shù)定義的源代碼中第一行的行號
-- 獲取當前棧的追溯信息
function traceback()
-- 獲取相應棧層上函數(shù)的信息
for level=1,math.huge do
-- 獲取函數(shù)信息
-- S 選擇
-- source 函數(shù)定義的位置
-- short_src 函數(shù)定義位置的短版本盒发,最多60個字符。
-- what 函數(shù)的類型
-- linedefined 函數(shù)定義在源代碼中第一行的行號
-- lastlinedefined 函數(shù)定義在源代碼中最后一行的行號
-- l 選擇
-- currentline 當前所在行
local info = debug.getinfo(level, "Sl")
-- 判斷是否具有上層函數(shù)
if not info then
break
end
-- 判斷是否為一個C函數(shù)
if info.what=="C" then
print(level, "C function")
else
print(string.format("file:%s line:%d", info.short_src, info.currentline))
end
end
end
traceback()
--[[
file:D:\lua\test\test.lua line:6
file:D:\lua\test\test.lua line:19
3 C function
--]]
debug.traceback([thread,][message[, level]])
獲取調用棧的回溯信息
debug.traceback
參數(shù)
-
message
字符串 可選項 被添加在椊品辏回溯信息的開頭宁舰。 -
level
數(shù)值 可選項 指明從棧的哪一層開始回溯,默認為1即調用traceback
的位置奢浑。
若有message
值且不是字符串或nil
蛮艰,traceback
函數(shù)不做任何處理直接返回message
,否則返回調用棧的回溯信息雀彼。
自定義的調試器
function __G__TRACKBACK__(errmsg)
print("LUA ERROR: "..tostring(errmsg).."\n")
print(debug.traceback("", 2))
end