并非所有应用程序都需要配置文件;许多应用程序从每次启动时都保持全新状态中获益。例如,简单的实用程序很少需要跨使用场景持久存在的首选项或设置。然而,当您编写复杂的应用程序时,用户能够配置他们如何与应用程序交互以及应用程序如何与他们的系统交互会更好。这就是配置文件的用途,本文讨论了使用 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
到您的主目录,而不是您的项目目录。您通常希望配置文件存在于您的应用程序之外,这样即使当用户卸载您的应用程序时,他们在使用该应用程序时生成的数据仍然保留在他们的系统上。用户可能会手动删除不必要的配置文件,但许多用户不会。因此,如果他们重新安装应用程序,它将保留他们的所有首选项。
配置文件位置在技术上并不重要,但每个操作系统 (OS) 都有一个规范或传统,规定它们应该放在哪里。在 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 文件
在建立包位置之后,接下来要做的是 require 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)
评论已关闭。