Lua IO庫詳解

I/O 庫提供了兩套不同風(fēng)格的文件處理接口。 第一種風(fēng)格使用隱式的文件句柄; 它提供設(shè)置默認(rèn)輸入文件及默認(rèn)輸出文件的操作, 所有的輸入輸出操作都針對(duì)這些默認(rèn)文件。 第二種風(fēng)格使用顯式的文件句柄。

當(dāng)使用隱式文件句柄時(shí), 所有的操作都由表 io 提供。 若使用顯式文件句柄, io.open 會(huì)返回一個(gè)文件句柄,且所有的操作都由該文件句柄的方法來提供。

表 io 中也提供了三個(gè) 和 C 中含義相同的預(yù)定義文件句柄: io.stdin io.stdout io.stderr。 I/O 庫永遠(yuǎn)不會(huì)關(guān)閉這些文件。

除非另有說明, I/O 函數(shù)在出錯(cuò)時(shí)都返回 nil (第二個(gè)返回值為錯(cuò)誤消息,第三個(gè)返回值為系統(tǒng)相關(guān)的錯(cuò)誤碼)。 成功時(shí)返回與 nil 不同的值

io:open(filename [, mode])

這個(gè)函數(shù)用字符串 mode 指定的模式打開一個(gè)文件。 返回新的文件句柄。 當(dāng)出錯(cuò)時(shí),返回 nil 加錯(cuò)誤消息。
mode 字符串可以是下列任意值:

  • **"r": **只讀模式,這也是對(duì)已存在的文件的默認(rèn)打開模式。
  • **"w": **可寫模式,允許修改已經(jīng)存在的文件和創(chuàng)建新文件(不可讀)。
  • **"a": **追加模式,對(duì)于已存的文件允許追加新內(nèi)容,但不允許修改原有內(nèi)容,同時(shí)也可以創(chuàng)建新文件。
  • **"r+": **讀寫模式打開已存的在文件。
  • **"w+": **如果文件已存在則刪除文件中數(shù)據(jù);若文件不存在則新建文件。讀寫模式打開。
  • **"a+": **以可讀的追加模式打開已存在文件,若文件不存在則新建文件。

mode 字符串可以在最后加一個(gè) 'b' , 這會(huì)在某些系統(tǒng)上以二進(jìn)制方式打開文件。

當(dāng)文件不存在時(shí)

local file = io.open("./test.txt")
file:close()

模式"r","r+",會(huì)提示錯(cuò)誤,這兩種模式不會(huì)自動(dòng)創(chuàng)建為難。
模式"a","a+","w","w+"都會(huì)創(chuàng)建文件

當(dāng)文件存在時(shí)
原文件:

test.txt
this is test 1
this is test 2

lua文件:

local file = io.open("./test.txt", mode)
print(file:write("123", "a"))
file:close()

local file = io.open("./test.txt", "r+")
print(file:read("*a"))
file:close()

對(duì)不同模式,分別調(diào)用讀寫操作

mode為"r"
Output:
寫:
nil Bad file descriptor 9

文件可讀,不可寫

mode為"r+"
Output :
true

文件內(nèi)容:
123a is test 1
this is test 2

文件內(nèi)容保留,新內(nèi)容從文件頭輸入
可讀

mode為"w"
Output :
true

文件內(nèi)容:
123a

讀:
nil No error    0

用輸入內(nèi)容覆蓋文件內(nèi)容
使用"w"模式打開文件時(shí),會(huì)立即刪除文件內(nèi)容,即使不寫入內(nèi)容.
用"w"模式讀時(shí),返回nil

mode為"w+"
Output:
true

文件內(nèi)容:
123a

用輸入內(nèi)容覆蓋文件內(nèi)容
使用"w+"模式打開文件時(shí),會(huì)立即刪除文件內(nèi)容
用"w+"模式讀時(shí),返回空字符串

mode為"a"
Output:
true

文件內(nèi)容:
this is test 1
this is test 2123a

讀:
nil No error    0

追加模式寫入
不可讀

mode為"a+"
Output:
true

文件內(nèi)容:
this is test 1
this is test 2123a

追加模式寫入
可讀


io:input([file])

用文件名調(diào)用它時(shí),(以文本模式)來打開該名字的文件, 并將文件句柄設(shè)為默認(rèn)輸入文件。 如果用文件句柄去調(diào)用它, 就簡(jiǎn)單的將該句柄設(shè)為默認(rèn)輸入文件。 如果調(diào)用時(shí)不傳參數(shù),它返回當(dāng)前的默認(rèn)輸入文件。
在出錯(cuò)的情況下,函數(shù)拋出錯(cuò)誤而不是返回錯(cuò)誤碼。

--文件名
io.input("./test.txt")
print(io.read("*a"))
io:close()

Output:
this is test 1
this is test 2

--文件句柄(需要使用可讀模式)
local file = io.open("./test.txt", "r")
print(io.input(file))
print(io.read("*a"))
print(file)
io.close()

Output:
file (777E1BD8)
this is test 1
this is test 2
file (777E1BD8

io:output([file])

用文件名調(diào)用它時(shí),(以文本模式)來打開該名字的文件, 并將文件句柄設(shè)為默認(rèn)輸出文件。 如果用文件句柄去調(diào)用它, 就簡(jiǎn)單的將該句柄設(shè)為默認(rèn)輸出文件。 如果調(diào)用時(shí)不傳參數(shù),它返回當(dāng)前的默認(rèn)輸出文件。
在出錯(cuò)的情況下,函數(shù)拋出錯(cuò)誤而不是返回錯(cuò)誤碼。

print(io.output("./test.txt"))
io.write("123")
io.close()

Output:
file (777E1BD8)

文件內(nèi)容:
123

io.popen (prog [, mode])

這個(gè)函數(shù)和系統(tǒng)有關(guān),不是所有的平臺(tái)都提供。

用一個(gè)分離進(jìn)程開啟程序 prog, 返回的文件句柄可用于從這個(gè)程序中讀取數(shù)據(jù) (如果 mode 為 "r",這是默認(rèn)值) 或是向這個(gè)程序?qū)懭胼斎耄ó?dāng) mode 為 "w" 時(shí))。


io.tmpfile()

返回一個(gè)臨時(shí)文件的句柄。 這個(gè)文件以更新模式打開,在程序結(jié)束時(shí)會(huì)自動(dòng)刪除。


io.type(obj)

檢查 obj 是否是合法的文件句柄。 如果 obj 它是一個(gè)打開的文件句柄,返回字符串 "file"。 如果 obj 是一個(gè)關(guān)閉的文件句柄,返回字符串 "closed file"。 如果 obj 不是文件句柄,返回 nil 。

local file = io.tmpfile()
print(io.type(file))
file:close()
print(io.type(file))
print(io.type({}))

Output:
file
closed file
nil

io.lines([filename])

提供一個(gè)循環(huán)迭代器以遍歷文件,如果指定了文件名則當(dāng)遍歷結(jié)束后將自動(dòng)關(guān)閉該文件;若使用默認(rèn)文件,則遍歷結(jié)束后不會(huì)自動(dòng)關(guān)閉文件。

for line in io.lines("./test.txt") do
    print(line)
end

Output:
this is test 1
this is test 2

注:Lua 5.3 有變動(dòng),添加模式數(shù)


file:lines()

返回一個(gè)迭代器函數(shù), 每次調(diào)用迭代器時(shí),都從文件中取一行數(shù)據(jù),和 io.lines 不同, 這個(gè)函數(shù)在循環(huán)結(jié)束后不會(huì)關(guān)閉文件。
注:Lua 5.3 有變動(dòng),添加模式數(shù)


file:read(...)

讀文件 file, 指定的格式?jīng)Q定了要讀什么。 對(duì)于每種格式,函數(shù)返回讀出的字符對(duì)應(yīng)的字符串或數(shù)字。 若不能以該格式對(duì)應(yīng)讀出數(shù)據(jù)則返回 nil。 (對(duì)于最后這種情況, 函數(shù)不會(huì)讀出后續(xù)的格式。) 當(dāng)調(diào)用時(shí)不傳格式,它會(huì)使用默認(rèn)格式讀下一行

  • *"n": ** 從文件當(dāng)前位置讀入一個(gè)數(shù)字,如果該位置不為數(shù)字則返回 nil。
  • *"l": ** 讀入當(dāng)前行。
  • *"a": ** 讀入從當(dāng)前文件指針位置開始的整個(gè)文件內(nèi)容。
  • number: 讀入指定字節(jié)數(shù)的內(nèi)容。
local file = io.open("./test.txt", "r")
print(file:read("*l"))
print(file:read("*n"))
print(file:read(2))

Output:
this is test 1
nil
th

注:Lua 5.3 有變動(dòng),去掉*號(hào),并添加"i"和"L"格式


io:read(...)

等價(jià)于 io.input():read(···)。


file:write(...)

將參數(shù)的值逐個(gè)寫入 file。 參數(shù)必須是字符串或數(shù)字。
成功時(shí),函數(shù)返回 file。 否則返回 nil 加錯(cuò)誤描述字符串。


io:write(...)

等價(jià)于 io.output():write(···)。


file:close()

關(guān)閉 file。 注意,文件在句柄被垃圾回收時(shí)會(huì)自動(dòng)關(guān)閉, 但是多久以后發(fā)生,時(shí)間不可預(yù)期的。


io:close()

等價(jià)于 file:close()。 不給出 file 時(shí)將關(guān)閉默認(rèn)輸出文件。


file:flush()

將寫入的數(shù)據(jù)保存到 file 中


io:flush()

等價(jià)于 io.output():flush()。


file:seek([whence [, offset]])

設(shè)置及獲取基于文件開頭處計(jì)算出的位置。 設(shè)置的位置由 offset 和 whence 字符串 whence 指定的基點(diǎn)決定?;c(diǎn)可以是:

  • **"set": **基點(diǎn)為 0 (文件開頭);
  • **"cur": **基點(diǎn)為當(dāng)前位置了;
  • **"end": **基點(diǎn)為文件尾;

當(dāng) seek 成功時(shí),返回最終從文件開頭計(jì)算起的文件的位置。 當(dāng) seek 失敗時(shí),返回 nil 加上一個(gè)錯(cuò)誤描述字符串。

whence 的默認(rèn)值是 "cur", offset 默認(rèn)為 0 。 因此,調(diào)用 file:seek() 可以返回文件當(dāng)前位置,并不改變它; 調(diào)用 file:seek("set") 將位置設(shè)為文件開頭(并返回 0); 調(diào)用 file:seek("end") 將位置設(shè)到文件末尾,并返回文件大小。

local file = io.open("./test.txt", "r+")
print(file:seek("end"))
print(file:seek("set"))
print(file:seek())
print(file:seek("cur", 10))
print(file:seek("cur"))
print(file:read(1))
print(file:seek("cur"))
file:write("123")
file:close()

Output:
30
0
0
10
10
s
11

修改文件的值會(huì)影響read操作 以及以"r+"模式打開文件的write操作

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,537評(píng)論 19 139
  • ¥開啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個(gè)線程,因...
    小菜c閱讀 7,317評(píng)論 0 17
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,641評(píng)論 18 399
  • 作者:云瑞微信公眾號(hào):馬虎眼 李坤是我的大學(xué)同學(xué),畢業(yè)后本來是想做技術(shù)開發(fā),寫代碼,跟自己的專業(yè)方向?qū)?,也找了?..
    astak3閱讀 325評(píng)論 1 0
  • 這是我看東野圭吾的第二本書,看完之后除了震撼,還有徘徊在內(nèi)心深處的不忍,百感交集,無論是桐原亮司,還是唐澤雪穗,讓...
    萌少年閱讀 2,417評(píng)論 5 14

友情鏈接更多精彩內(nèi)容