Latest web development tutorials

Lua 文件I/O

Lua I/O 庫用於讀取和處理文件。 分為簡單模式(和C一樣)、完全模式。

  • 簡單模式(simple model)擁有一個當前輸入文件和一個當前輸出文件,並且提供針對這些文件相關的操作。
  • 完全模式(complete model) 使用外部的文件句柄來實現。 它以一種面對對象的形式,將所有的文件操作定義為文件句柄的方法

簡單模式在做一些簡單的文件操作時較為合適。 但是在進行一些高級的文件操作的時候,簡單模式就顯得力不從心。 例如同時讀取多個文件這樣的操作,使用完全模式則較為合適。

打開文件操作語句如下:

file = io.open (filename [, mode])

mode 的值有:

模式 描述
r 以只讀方式打開文件,該文件必須存在。
w 打開只寫文件,若文件存在則文件長度清為0,即該文件內容會消失。 若文件不存在則建立該文件。
a 以附加的方式打開只寫文件。 若文件不存在,則會建立該文件,如果文件存在,寫入的數據會被加到文件尾,即文件原先的內容會被保留。 (EOF符保留)
r+ 以可讀寫方式打開文件,該文件必須存在。
w+ 打開可讀寫文件,若文件存在則文件長度清為零,即該文件內容會消失。 若文件不存在則建立該文件。
a+ 與a類似,但此文件可讀可寫
b 二進制模式,如果文件是二進製文件,可以加上b
+ 號表示對文件既可以讀也可以寫

簡單模式

簡單模式使用標準的I/O 或使用一個當前輸入文件和一個當前輸出文件。

以下為file.lua 文件代碼,操作的文件為test.lua(如果沒有你需要創建該文件),代碼如下:

-- 以只读方式打开文件
file = io.open("test.lua", "r")

-- 设置默认输入文件为 test.lua
io.input(file)

-- 输出文件第一行
print(io.read())

-- 关闭打开的文件
io.close(file)

-- 以附加的方式打开只写文件
file = io.open("test.lua", "a")

-- 设置默认输出文件为 test.lua
io.output(file)

-- 在文件最后一行添加 Lua 注释
io.write("--  test.lua 文件末尾注释")

-- 关闭打开的文件
io.close(file)

執行以上代碼,你會發現,輸出了test.ua 文件的第一行信息,並在該文件最後一行添加了lua 的註釋。 如我這邊輸出的是:

-- test.lua 文件

在以上實例中我們使用了io."x" 方法,其中io.read() 中我們沒有帶參數,參數可以是下表中的一個:

模式 描述
"*n" 讀取一個數字並返回它。 例:file.read("*n")
"*a" 從當前位置讀取整個文件。 例:file.read("*a")
"*l"(默認) 讀取下一行,在文件尾(EOF) 處返回nil。 例:file.read("*l")
number 返回一個指定字符個數的字符串,或在EOF 時返回nil。 例:file.read(5)

其他的io 方法有:

  • io.tmpfile():返回一個臨時文件句柄,該文件以更新模式打開,程序結束時自動刪除

  • io.type(file):檢測obj是否一個可用的文件句柄

  • io.flush():向文件寫入緩衝中的所有數據

  • io.lines(optional file name):返回一個迭代函數,每次調用將獲得文件中的一行內容,當到文件尾時,將返回nil,但不關閉文件


完全模式

通常我們需要在同一時間處理多個文件。 我們需要使用file:function_name 來代替io.function_name 方法。 以下實例演示瞭如同同時處理同一個文件:

-- 以只读方式打开文件
file = io.open("test.lua", "r")

-- 输出文件第一行
print(file:read())

-- 关闭打开的文件
file:close()

-- 以附加的方式打开只写文件
file = io.open("test.lua", "a")

-- 在文件最后一行添加 Lua 注释
file:write("--test")

-- 关闭打开的文件
file:close()

執行以上代碼,你會發現,輸出了test.ua 文件的第一行信息,並在該文件最後一行添加了lua 的註釋。 如我這邊輸出的是:

-- test.lua 文件

read 的參數與簡單模式一致。

其他方法:

  • file:seek(optional whence, optional offset):設置和獲取當前文件位置,成功則返回最終的文件位置(按字節),失敗則返回nil加錯誤信息。參數whence 值可以是:

    • "set": 從文件頭開始
    • "cur": 從當前位置開始[默認]
    • "end": 從文件尾開始
    • offset:默認為0
    不帶參數file:seek()則返回當前位置,file:seek("set")則定位到文件頭,file:seek("end")則定位到文件尾並返回文件大小
  • file:flush():向文件寫入緩衝中的所有數據

  • io.lines(optional file name):打開指定的文件filename為讀模式並返回一個迭代函數,每次調用將獲得文件中的一行內容,當到文件尾時,將返回nil,並自動關閉文件。
    若不帶參數時io.lines() <=> io.input():lines(); 讀取默認輸入設備的內容,但結束時不關閉文件,如

    for line in io.lines("main.lua") do
    
      print(line)
    
      end
    

以下實例使用了seek 方法,定位到文件倒數第25 個位置並使用read 方法的*a 參數,即從當期位置(倒數第25 個位置)讀取整個文件。

-- 以只读方式打开文件
file = io.open("test.lua", "r")

file:seek("end",-25)
print(file:read("*a"))

-- 关闭打开的文件
file:close()

我這邊輸出的結果是:

st.lua 文件末尾--test