[Lua]Lua IO庫整理
I/O庫為檔案操作提供了兩種不同的模型,簡單模型和完整模型。簡單模型假設有一個當前輸入檔案和一個當前輸出檔案,它的I/O操作均作用於這些檔案。完整模型則使用顯式地檔案控制代碼。它採用了面向物件的風格,並將所有的操作定義為檔案控制代碼上的方法。
簡單IO模式
簡單模型的所有操作都作用於兩個當前檔案。I/O庫將當前輸入檔案初始化為程序標準輸入(stdin),將當前輸出檔案初始化為程序標準輸出。在執行io.read()操作時,就會從標準輸入中讀取一行。
用函式io.input和io.output可以改變這兩個當前檔案。io.input(filename)呼叫會以只讀模式開啟指定的檔案,並將其設定為當前輸入檔案;除非再次呼叫
io.write, io.read 是一對.預設情況下,他們從stdin讀輸入,輸出到stdout。 另有兩個函式可以改變這一預設行為: io.input("xx"), io.output("yy") 他們改變輸入為某個 xx 檔案, 輸出到 yy 檔案。 eg:
如果 io.read()引數
"*all" | 從當前位置讀取整個檔案,若為檔案尾,則返回空字串 |
"*line" | [預設]讀取下一行的內容,若為檔案尾,則返回nil |
"*number" | 讀取指定位元組數的字元,如果number為0則返回空字串,若為檔案尾,則返回 |
<num> | 讀取num個字元到串 |
--[[test.lua的內容
hello world,I is test.lua
print(123)
--]]
io.input("E:\\workplace\\project\\server\\script\\test\\src\\test.lua")
t=io.read("*all")
io.write(t, '\n') ------輸出整個 test.lua 檔案的內容到 stdin
--> --hello world,I is test.lua
--> print(123)
函式名 | 功能描述 |
io.close([file]) | 相當於file:close(),關閉預設的輸出檔案 |
io.flush() | 相當於file:flush(),輸出所有緩衝中的內容到預設輸出檔案 |
io.lines ([filename]) | 開啟指定的檔案filename為讀模式並返回一個迭代函式,每次呼叫將獲得檔案中的一行內容,當到檔案尾時,將返回nil,並自動關閉檔案 |
io.input ([file]) | |
io.output ([file]) | 相當於io.input,但操作在預設輸出檔案上 |
io.read (...) | 相當於io.input():read |
io.write (...) | 相當於io.output():write |
io.tmpfile () | 返回一個臨時檔案控制代碼,該檔案以更新模式開啟,程式結束時自動刪除 |
io.type (obj) | 檢測obj是否一個可用的檔案控制代碼;返回: |
--print與io.write的不同
--Write函式與print函式不同在於,write不附加任何額外的字元到輸出中去,例如製表符,換行符等等。還有write函式是使用當前輸出檔案,而print始終使用標準輸出。另外print函式會自動呼叫引數的tostring方法,所以可以顯示出表(tables)函式(functions)和nil。
print("hello", "Lua");
print("Hi")
--> hello Lua
--> Hi
io.write("hello", "Lua");
io.write("Hi", "\n")
--> helloLuaHi
-- Opens a file in read
local file = io.open("E:\\workplace\\project\\server\\script\\test\\src\\test.lua", "r")
io.input(file)--設定當前檔案為預設輸出檔案
print(io.read())--預設讀取第一行
--> --hello world,I is test.lua
io.close(file)--關閉
-- Opens a file in append mode
file = io.open("E:\\workplace\\project\\server\\script\\test\\src\\test.lua", "a")
-- sets the default output file as test.lua
io.output(file)
-- appends a word test to the last line of the file
io.write("-- End of the test.lua file\n")
-- closes the open file
io.close(file)
--[[操作前
--hello world,I is test.lua
print(123)
--]]
--[[操作後
--hello world,I is test.lua
print(123)-- End of the test.lua file
--]]
完全IO模式
簡單I/O功能太受限了,以至於基本沒有什麼用處,而用的更多的則是這裡說的完整I/O模型。完整I/O模型可以進行更多的I/O控制,它是基於檔案控制代碼的,就好比與C語言中的FILE*,表示一個正在操作的檔案。
要開啟一個檔案,可以使用io.open函式,它有兩個引數,一個表示要開啟的檔名,另一個表示操作的模式字串。模式字串可以有以下四種取值方式:io.open(filename,[mode])的mode取值
"r" | 是隻讀方式開啟(預設), 不能寫入。 |
"w" | 只寫方式開啟,不能讀取。 |
"a" | 追加開啟一個現有的檔案或進行追加建立一個新的檔案模式。 |
"r+" | 以讀寫方式開啟,保留原有資料。這個模式是自由度最高的。 |
"w+" | 以讀寫方式開啟,刪除原有資料。就是開啟後文件是空檔案。 |
"a+" | 以讀寫方式開啟,保留原有資料,只能在檔案末尾新增,不能在檔案中間改寫資料。若找不到檔案,也會建立新檔案 |
"b" | 某些系統支援二進位制方式 |
正常情況下open函式返回一個檔案的控制代碼。如果發生錯誤,則返回nil,以及一個錯誤資訊和錯誤程式碼。
當成功開啟一個檔案以後,就可以使用read/write方法讀寫檔案了,這與read/write函式相似,但是需要用冒號語法,將它們作為檔案控制代碼的方法來呼叫
函式名 | 功能描述 |
io.open (filename [, mode]) | 按指定的模式開啟一個檔案,成功則返回檔案控制代碼,失敗則返回nil+錯誤資訊 |
file:close() | 關閉檔案 |
file:flush() | 向檔案寫入緩衝中的所有資料 |
file:lines() | 返回一個迭代函式,每次呼叫將獲得檔案中的一行內容,當到檔案尾時,將返回nil,但不關閉檔案 如:for line in file:lines() do body end |
file:read(...) | 按指定的格式讀取一個檔案,按每個格式函式將返回一個字串或數字,如果不能正確讀取將返回nil,若沒有指定格式將指預設按行方式進行讀取 |
file:write(...) | 按指定的引數格式輸出檔案內容,引數必須為字元或數字,若要輸出其它值,則需通過tostring或string.format進行轉換 |
file:seek([whence][,offset]) | 置和獲取當前檔案位置,成功則返回最終的檔案位置(按位元組),失敗則返回nil加錯誤資訊whence: |
file:setvbuf(mode,[,size]) | 設定輸出檔案的緩衝模式mode: |
-- Opens a file in read mode
file = io.open("E:\\workplace\\project\\server\\script\\test\\src\\test.lua", "r")
-- prints the first line of the file
print(file:read())
--> --hello world,I is test.lua
-- closes the opened file
file:close()
-- Opens a file in append mode
file = io.open("E:\\workplace\\project\\server\\script\\test\\src\\test.lua", "a")
-- appends a word test to the last line of the file
file:write("--test\n")
-- closes the open file
file:close()
--[[操作前
--hello world,I is test.lua
print(123)-- End of the test.lua file
--]]
--[[操作後
--hello world,I is test.lua
print(123)-- End of the test.lua file
--test
--]]
Lua IO庫擴充套件
--------------------------------
-- @module io
-- start --
--------------------------------
-- 檢查指定的檔案或目錄是否存在,如果存在返回 true,否則返回 false
-- @function [parent=#io] exists
-- @param string path 要檢查的檔案或目錄的完全路徑
-- @return boolean#boolean
--[[--
檢查指定的檔案或目錄是否存在,如果存在返回 true,否則返回 false
可以使用 cc.FileUtils:fullPathForFilename() 函式查詢特定檔案的完整路徑,例如:
~~~ lua
local path = cc.FileUtils:getInstance():fullPathForFilename("gamedata.txt")
if io.exists(path) then
....
end
~~~
]]
-- end --
function io.exists(path)
local file = io.open(path, "r")
if file then
io.close(file)
return true
end
return false
end
-- start --
--------------------------------
-- 讀取檔案內容,返回包含檔案內容的字串,如果失敗返回 nil
-- @function [parent=#io] readfile
-- @param string path 檔案完全路徑
-- @return string#string
--[[--
讀取檔案內容,返回包含檔案內容的字串,如果失敗返回 nil
io.readfile() 會一次性讀取整個檔案的內容,並返回一個字串,因此該函式不適宜讀取太大的檔案。
]]
-- end --
function io.readfile(path)
local file = io.open(path, "r")
if file then
local content = file:read("*a")
io.close(file)
return content
end
return nil
end
-- start --
--------------------------------
-- 以字串內容寫入檔案,成功返回 true,失敗返回 false
-- @function [parent=#io] writefile
-- @param string path 檔案完全路徑
-- @param string content 要寫入的內容
-- @param string mode 寫入模式,預設值為 "w+b"
-- @return boolean#boolean
--[[--
以字串內容寫入檔案,成功返回 true,失敗返回 false
"mode 寫入模式" 引數決定 io.writefile() 如何寫入內容,可用的值如下:
- "w+" : 覆蓋檔案已有內容,如果檔案不存在則建立新檔案
- "a+" : 追加內容到檔案尾部,如果檔案不存在則建立檔案
此外,還可以在 "寫入模式" 引數最後追加字元 "b" ,表示以二進位制方式寫入資料,這樣可以避免內容寫入不完整。
**Android 特別提示:** 在 Android 平臺上,檔案只能寫入儲存卡所在路徑,assets 和 data 等目錄都是無法寫入的。
]]
-- end --
function io.writefile(path, content, mode)
mode = mode or "w+b"
local file = io.open(path, mode)
if file then
if file:write(content) == nil then return false end
io.close(file)
return true
else
return false
end
end
-- start --
--------------------------------
-- 拆分一個路徑字串,返回組成路徑的各個部分
-- @function [parent=#io] pathinfo
-- @param string path 要分拆的路徑字串
-- @return table#table
--[[--
拆分一個路徑字串,返回組成路徑的各個部分
~~~ lua
local pathinfo = io.pathinfo("/var/app/test/abc.png")
-- 結果:
-- pathinfo.dirname = "/var/app/test/"
-- pathinfo.filename = "abc.png"
-- pathinfo.basename = "abc"
-- pathinfo.extname = ".png"
~~~
]]
-- end --
function io.pathinfo(path)
local pos = string.len(path)
local extpos = pos + 1
while pos > 0 do
local b = string.byte(path, pos)
if b == 46 then -- 46 = char "."
extpos = pos
elseif b == 47 then -- 47 = char "/"
break
end
pos = pos - 1
end
local dirname = string.sub(path, 1, pos)
local filename = string.sub(path, pos + 1)
extpos = extpos - pos
local basename = string.sub(filename, 1, extpos - 1)
local extname = string.sub(filename, extpos)
return {
dirname = dirname,
filename = filename,
basename = basename,
extname = extname
}
end
-- start --
--------------------------------
-- 返回指定檔案的大小,如果失敗返回 false
-- @function [parent=#io] filesize
-- @param string path 檔案完全路徑
-- @return integer#integer
-- end --
function io.filesize(path)
local size = false
local file = io.open(path, "r")
if file then
local current = file:seek()
size = file:seek("end")
file:seek("set", current)
io.close(file)
end
return size
end
這些quick_cocos中的