我正在编写App,需要在开始时读取配置。有些不是工作所必需的。
class ParseConfig
{
string optionalkey;
//...
this()
{
this.optionalkey = config.getKey("key1");
}
//...
}
如果不存在和配置,我需要找到跳过(不要尝试查找和解析)的问题。现在App尝试解析配置并向我显示错误。
我发现只有一种方法 - 将所有内容包装在try-catch块中,如果在cantch block中的config中找不到值,则将其设置为null。
最好的方法是什么?
我正在使用dini进行配置。
upd :(添加示例)
import std.stdio;
import std.path;
import std.file;
import dini;
void main()
{
string confpath = buildPath(getcwd, "config.ini");
if (!exists(confpath)) throw new Exception("ERROR: config.ini do not exists");
auto config = Ini.Parse(confpath);
try
{
string optionalkey;
if(config.getKey("optionalkey"))
{
optionalkey = config.getKey("optionalkey");
}
writeln(optionalkey); // nothing will shown, becouse exception
}
catch( Exception e)
{
writeln("Exception! :(");
writeln(e.msg);
}
}
答案 0 :(得分:2)
捕获异常是一种方式,但它并不完美(主要是在有许多可选配置的情况下)。所以更好的方法是测试密钥是否存在:
class ParseConfig
{
string optionalkey;
//...
this()
{
this.optionalkey = config.hasKey("key1") ? config.getKey("key1") : "defaultValue";
}
//...
}
但理想的情况是,如果dini有getKey方法的重载,那么你可以使用这样的东西:
this.optionalkey = config.getKey("key1", "defaultValue");
但是从我看来它没有它的来源,但我打算添加它并制作PR。
<强>更新强>
答案 1 :(得分:2)
今天写了一个非常高级的ini文件包装器,它支持部分,注释,线程安全,读取的默认值,使用模板值写入/读取,输入检查等。
你可以在这里得到它: https://github.com/BaussProjects/baussini
以下是一个示例用法(来自repo的example.d)
module main;
import baussini;
import std.stdio : writefln, readln;
void main() {
string fileName = "test.ini";
// Thread-safe instance, for a non thread-safe instance replace "true" with "false"
auto ini = new IniFile!(true)(fileName);
// Use open() for reading and close() for write. Both can be combined ...
if (!ini.exists()) {
ini.addSection("Root");
// Write way 1
ini.write!string("Root", "StringValue1", "Hello World!");
// Write way 2
ini.getSection("Root").write!int("IntValue1", 9001);
// Write way 3
ini.getSection("Root")
.write!string("StringValue2", "Hello Universe!")
.write!int("IntValue2", 1000000);
ini.close();
}
else {
ini.open();
// Read way 1
string stringValue1 = ini.read!string("Root", "StringValue1");
// Read way 2
int intValue1 = ini.getSection("Root").read!int("IntValue1");
// Read way 3
string stringValue2;
int intValue2;
ini.getSection("Root")
.read!string("StringValue2", stringValue2)
.read!int("IntValue2", intValue2);
writefln("%s is %s", "stringValue1", stringValue1);
writefln("%s is %s", "intValue1", intValue1);
writefln("%s is %s", "stringValue2", stringValue2);
writefln("%s is %s", "intValue2", intValue2);
readln();
}
}
在你的情况下你可以使用IniFile.hasKey或IniSection()。hasKey() 例如:
// Check way 1
if (ini.hasKey("Root", "StringValue1")) {
// The section "Root" has an entry named "StringValue1"
}
// Check way 2
auto section = ini.getSection("Root");
if (section.hasKey("StringValue1")) {
// The section "Root" has an entry named "StringValue1"
}
您也可以使用默认值。
string stringValue1 = ini.getSection("Root").read!string("StringValue1", "Default");
// stringValue1 will be "Default" if it doesn't exist within "Root"
默认值必须是字符串输入,但它总是将其值转换为T. 实施例
int defaultValue = ini.getSection("Root").read!int("IntValue3", "1000");
// defaultValue will be 1000 if it doesn't exist within "Root"
答案 2 :(得分:1)
您可以使用hasKey
class ParseConfig
{
string optionalkey;
//...
this()
{
if (config.hasKey("key1"))
this.optionalkey = config.getKey("key1");
}
//...
}
假设我们谈论same dini