使用 Lua 解析配置文件
使用 Lua 配置持久化應用設置。
不是所有的應用都需要配置文件;對很多應用來說,在啟動時變得煥然一新對它們更有利。例如,簡單的工具就極少需要偏好項和設置在使用過程中保持穩定不變。然而,當你編寫一個複雜的應用程序時,如果能讓用戶設置與應用的交互方式,以及應用與系統交互的方式會很不錯。這就是配置文件用來做的事情。本文將討論一些利用 Lua 進行持久化配置的方法。
選擇一種格式
關於配置文件很重要的兩點是一致性和可預見性。你不會希望為了保存用戶偏好項,將信息轉儲到文件中,然後再花幾天去編碼實現「逆向工程」,處理最後出現在文件里的隨機信息。
這裡用一些常用的 配置文件格式。Lua 有一些庫可以處理大多數常用的配置格式;在本文中,我會採用 INI 格式。
安裝庫
Lua 庫的核心倉庫是 Luarocks.org。你可以在這個網站搜索庫,或者你可以安裝並使用 luarocks
終端命令。
Linux 環境中,你可以從發行版的軟體倉庫中下載它,例如:
$ sudo dnf install luarocks
在 macOS 上,請使用 MacPorts 或者 Homebrew。在 Windows 上,請使用 Chocolatey。
luarocks
安裝後,你可以使用 search
子命令來搜索一個恰當的庫。如果你不知道庫的名字,可以通過關鍵詞來搜索這個庫,例如 ini
、xml或者
json,這取決於你想要用這個庫做什麼。打個比方,你可以搜索
inifile`, 這個庫被我用來解析 INI 格式的文本文件。
$ luarocks search inifile
Search results:
inifile
1.0-2 (rockspec) - https://luarocks.org
1.0-2 (src) - https://luarocks.org
1.0-1 (rockspec) - https://luarocks.org
[...]
一個開發者容易犯的錯誤是在系統上安裝了這個庫卻忘了把它和應用打包。這會給沒有安裝這個庫的用戶帶來麻煩。為了防止這個問題發生,可以使用 --tree
選項將它安裝在項目的本地文件夾中。如果你沒有這個項目文件夾,那就先創建這個文件夾再安裝庫:
$ mkdir demo
$ cd demo
$ luarocks install --tree=local inifile
--tree
選項指示 luarocks
創建一個新文件夾並在其中安裝你的庫,例如這個例子中的 local
文件夾。 使用這個簡單的技巧,你可以將所有你項目要使用的依賴項直接安裝到項目文件夾中。
配置代碼
首先,在一個名 myconfig.ini
的文件中創建一些 INI 數據。
[example]
name=Tux
species=penguin
enabled=false
[demo]
name=Beastie
species=demon
enabled=false
將這個文件保存到你的主目錄下,命名為 myconfig.ini
, 不要 存到項目文件夾下。你通常會希望配置文件獨立於你的文件存在,這樣當用戶卸載你的應用時,使用應用時產生的數據可以保存在系統中。有些用戶會刪除不重要的配置文件,但大多數不會。最終,如果他們要重裝這個應用,還會保留著所有的用戶偏好項。
配置文件的位置以技術來說並不重要,但每一個操作系統都有存儲它們的特定或者默認的路徑。在 Linux 中,這個路徑由 Freedesktop 規範 指定。它規定配置文件被保存在一個名為 ~/.config
的隱藏文件夾中。為了操作時更加清晰明確,可以在主目錄下存儲配置文件,以便於使用和尋找。
創建第二個文件,命名為 main.lua
,並在你喜歡的文本編輯器中打開它。
首先,你必須告訴 Lua 你將想要使用的附加庫放置在哪裡。package.path
變數決定了 Lua 到哪裡去尋找這些庫。你可以從終端中查看 Lua 默認的包地址:
$ Lua
> print(package.path)
./?.lua;/usr/share/lua/5.3/?.lua;/usr/share/lua/5.3/?/init.lua;/usr/lib64/lua/5.3/?.lua;/usr/lib64/lua/5.3/?/init.lua
在你的 Lua 代碼中,將你本地庫的路徑添加到 package.path
中:
package.path = package.path .. ';local/share/lua/5.3/?.lua
使用 Lua 解析 INI 文件
當包的位置確定以後,下一件事就是引入 inifile
庫並處理一些操作系統邏輯。即使這是一個很簡單的應用,代碼也需要從操作系統獲取到用戶主目錄的路徑,並建立在必要時將文件系統路徑返回給操作系統的通信方式。
package.path = package.path .. ';local/share/lua/5.3/?.lua
inifile = require('inifile')
-- find home directory
home = os.getenv('HOME')
-- detect path separator
-- returns '/' for Linux and Mac
-- and '' for Windows
d = package.config:sub(1,1)
現在你可使用 inifile
來從配置文件解析數據到 Lua 表中。一旦這些數據被導入進表中,你可以像查詢其他的 Lua 表一樣查詢它。
-- parse the INI file and
-- put values into a table called conf
conf = inifile.parse(home .. d .. 'myconfig.ini')
-- print the data for review
print(conf['example']['name'])
print(conf['example']['species'])
print(conf['example']['enabled'])
在終端中運行代碼可以看見結果:
$ lua ./main.lua
Tux
penguin
false
這看起來是正確的。試試在 demo
塊中執行同樣的操作。
使用 INI 格式存儲數據
不是所有用來解析的庫都會讀寫數據(通常被稱為 _編碼 和 解碼),但是 inifile
會這樣做。這意味著你可以使用它對配置文件進行修改。
為了改變配置文件中的值,你可以對被解析的表中的變數進行設置,然後把表重寫回配置文件中。
-- set enabled to true
conf['example']['enabled'] = true
conf['demo']['enabled'] = true
-- save the change
inifile.save(home .. d .. 'myconfig.ini', conf)
現在再來看看配置文件:
$ cat ~/myconfig.ini
[example]
name=Tux
species=penguin
enabled=true
[demo]
name=Beastie
species=demon
enabled=true
配置文件
按照用戶的設想來存儲數據對程序來說是至關重要的。幸運的是,這對工程師來說是一個很常規的任務,大多數工作可能早已被完成了。只要找到一個好用的庫完成開放格式下編碼和解碼,你就能為用戶提供一致且持續的體驗。
以下是完整的演示代碼,可供參考。
package.path = package.path .. ';local/share/lua/5.3/?.lua'
inifile = require('inifile')
-- find home directory
home = os.getenv('HOME')
-- detect path separator
-- returns '/' for Linux and Mac
-- and '' for Windows
d = package.config:sub(1,1)
-- parse the INI file and
-- put values into a table called conf
conf = inifile.parse(home .. d .. 'myconfig.ini')
-- print the data for review
print(conf['example']['name'])
print(conf['example']['species'])
print(conf['example']['enabled'])
-- enable Tux
conf['example']['enabled'] = true
-- save the change
inifile.save(home .. d .. 'myconfig.ini', conf)
via: https://opensource.com/article/21/6/parsing-config-files-lua
作者:Seth Kenlon 選題:lujun9972 譯者:hadisi1993 校對:wxy
本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive