# 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
```
- Lua 簡介
- Lua 環境安裝
- Lua 數據類型
- Lua 變量
- Lua 循環
- Lua while 循環
- Lua for 循環
- Lua repeat...until 循環
- Lua 循環嵌套
- Lua break 語句
- Lua 流程控制
- Lua if 語句
- Lua if...else 語句
- Lua if 嵌套語句
- Lua 函數
- Lua 運算符
- Lua 字符串
- Lua 數組
- Lua 迭代器
- Lua table(表)
- Lua 模塊與包
- Lua 元表(Metatable)
- Lua 協同程序(coroutine)
- Lua 文件 I/O
- Lua 錯誤處理
- Lua 調試(Debug)
- Lua 垃圾回收
- Lua 面向對象
- Lua 數據庫訪問