Lua標準庫

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.gmatchstring.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:plaintrue表示關閉模式匹配機制秦驯,此時函數(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庫

數(shù)學庫
-- 獲取圓周率
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中抑堡。

操作系統(tǒng)庫

日期時間

  • 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.dateos.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.stdinio.stdout允悦、io.stderr膝擂。IO庫永遠不會關閉這些文件。

使用io表隙弛,io.open()將返回指定文件的描述架馋,且所有的操作將圍繞這個文件描述io表同樣提供3中預定義的文件描述:io.stdinio.stdout全闷、io.stderr叉寂。

  • 文件句柄直接調用方式

使用file:xxx()函數(shù)方式進行操作,其中fileioi.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.writeprint不同之處在于裹唆,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_srcsource的短版本躬翁,最多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
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末壤蚜,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子徊哑,更是在濱河造成了極大的恐慌袜刷,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件莺丑,死亡現(xiàn)場離奇詭異著蟹,居然都是意外死亡,警方通過查閱死者的電腦和手機梢莽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進店門萧豆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人昏名,你說我怎么就攤上這事涮雷。” “怎么了轻局?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵份殿,是天一觀的道長。 經(jīng)常有香客問我嗽交,道長卿嘲,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任夫壁,我火速辦了婚禮拾枣,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己梅肤,他們只是感情好司蔬,可當我...
    茶點故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著姨蝴,像睡著了一般俊啼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上左医,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天授帕,我揣著相機與錄音,去河邊找鬼浮梢。 笑死跛十,一個胖子當著我的面吹牛,可吹牛的內容都是我干的秕硝。 我是一名探鬼主播芥映,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼远豺!你這毒婦竟也來了奈偏?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤躯护,失蹤者是張志新(化名)和其女友劉穎霎苗,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體榛做,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年内狸,在試婚紗的時候發(fā)現(xiàn)自己被綠了检眯。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,977評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡昆淡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情皇筛,我是刑警寧澤炒刁,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站眨补,受9級特大地震影響管削,放射性物質發(fā)生泄漏。R本人自食惡果不足惜撑螺,卻給世界環(huán)境...
    茶點故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一含思、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦含潘、人聲如沸饲做。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽盆均。三九已至,卻和暖如春漱逸,著一層夾襖步出監(jiān)牢的瞬間泪姨,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工虹脯, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留驴娃,地道東北人。 一個月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓循集,卻偏偏與公主長得像唇敞,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子咒彤,可洞房花燭夜當晚...
    茶點故事閱讀 44,927評論 2 355

推薦閱讀更多精彩內容

  • Lua 5.1 參考手冊 by Roberto Ierusalimschy, Luiz Henrique de F...
    蘇黎九歌閱讀 13,797評論 0 38
  • lua基礎數(shù)據(jù)類型 nil 一個變量在第一次賦值前的默認值是 nil疆柔, 將nil 賦予給一個全局變量就等同于刪除它...
    毛球小二閱讀 2,021評論 0 6
  • ORA-00001: 違反唯一約束條件 (.) 錯誤說明:當在唯一索引所對應的列上鍵入重復值時,會觸發(fā)此異常镶柱。 O...
    我想起個好名字閱讀 5,317評論 0 9
  • 具體在quick-cocos2d-x 框架:framework->function.lua 文件中 --[[-- ...
    曾令偉閱讀 337評論 0 0
  • 比"活在當下"更重要的是"活在未來"的能力旷档。“活在未來”歇拆,指的是要我們通過不斷地學習鞋屈,時刻保持敏銳的觀察力和預測能...
    齊齊樂閱讀 662評論 2 2