ini文件最大好处就是 无污染
注册表的最大好处就是 隐密!
(1) 注册表 采用的是二进制形式登录数据,INI 文件采用的则是简单的文本形式登录数据。
(2) 注册表 支持子关键字,各级子关键字都有自己的“键值”;INI 文件中则支持小节以及小节中的设置行参数。
(3) Registry 可以包括子键,而 INI 文件不支持小节的嵌套。
(4) Registry 中的键值项还可以包含可执行代码,而在INI文件中设置项只是简单的字串。
(5) 在同一台计算机上有多个用户,Registry 可以存储每个用户的特性,而INI文件中却不可能。
在功能上,注册表与.INI文件相比,主要有以下3个特点:
(1) 注册表允许对硬件、某些操作系统参数、应用程序和设备驱动程序进行跟踪配置,这使得某些配置的改变(如“控制面板”中的选项等)可以在不重新启动系统的情况下立即生效。
(2) 注册表中登录的硬件部分数据可以用来支持Windows 98的即插即用特性。当Windows 98检测到机器上的各种设备时,就把有关数据保存到注册表中。通常是在安装时进行这种检测的,但Windows 98启动或原有配置改变时,也要进行检测。如安装一个新的硬件时,Windows 98将检查注册表,以便确定哪些资源已被占用,这样就可以避免新设备与原有设备之间的资源冲突。
(3) 通过注册表,管理人员和用户可以在网络上检查系统的配置和设置,使得远程管理得以实现。
软件占用内存:
注册表不是一次全部都加载到内存中, 有些部分只有在要用时才会调入内存.
保密性:
根据微软的推荐,用 注册表 还是好些,因为你可以加上他的安全策略保护注册表,因而也保证了你的程序相关数据的保密性,而用ini文件你又要自己定作加密算法了
注册表主要是为了解决ini文件很难做到支持3维表格的问题,而且可以让多个系统共享数据。
注册表写的数据多了不会占内存,但是会减慢 WINDOWS 的速度!
因为注册表写得多了,垃圾太多,数据庞大检索速度必能要慢!
注册表很容易留下垃圾,越弄越大。 - 在卸载程序时,不能完整地卸载,会留下痕迹
如果不涉及到复杂的多用户,用ini我个人认为比较好。
软件卸载时,不会留下痕迹
易读、易复制
QSettings类提供了持久的跨平台应用程序设置。
用户通常期望应用程序记住它的设置(窗口大小、位置等)所有会话。这些信息通常存储在 Windows 系统注册表,OS X和iOS的属性列表文件中。在Unix系统中,在缺乏标准的情况下,许多应用程序(包括KDE应用程序)使用INI文本文件。
QSettings围绕这些抽象技术,使我们能够以便携的方式保存和恢复应用程序设置。它还支持自定义存储格式。
QSettings API基于QVariant,可以保存很多基础的类型,比如 QString、QRect、QImage等。
如果你需要的是一个非持久性的基于内存结构,可以考虑使用QMap
代替
QSettings是 qt 提供的一个读取配置文件的类,在 windows平台,它提供了ini文件读些,注册表读写的功能。
使用 QSettings::Format 来区分
QSettings::Format 有两种:
QSettings::NativeFormat -- 在windows平台可以读写windows注册表.
QSettings::IniFormat -- 可以读写ini格式的配置文件
在Unix/X11平台下这两个Format效果是一样的。
在 windows 平台, QSettings 默认是访问注册表,如:
// main.cpp
QApplication app(argc, argv);
app.setApplicationName("AppName");
app.setOrganizationName("Organ");
//写入 - 最终是写到了,注册表 \HKEY_CURRENT_USER\Software\Organ\AppName\Language 中
{
QSettings settings;
settings.beginGroup("Language");
if (strLocal.isEmpty())
settings.remove(QLatin1String("currentLanguage"));
else
settings.setValue(QLatin1String("currentLanguage"), strLocal);
settings.endGroup();
}
// 读取 - 从注册表 \HKEY_CURRENT_USER\Software\Organ\AppName\Language 中读取
{
QSettings settings;
settings.beginGroup(QLatin1String("Language"));
QString str_lan = settings.value(QLatin1String("currentLanguage")).toString();
settingsTranslation.endGroup();
}
当创建一个QSettings对象时,必须通过指定公司或组织名称以及产品名称,例如:公司名称为:MySoft,产品名为:Star Runner,那么可以用下列方式来构造QSettings对象:
QSettings settings("MySoft", "Star Runner");
QSettings对象既可以创建在栈上,也可以创建在堆(即使用new)上,构建和销毁也非常快。
如果你的应用程序在很多地方使用QSettings,则可以使用QCoreApplication::setOrganizationName()
和 QCoreApplication::setApplicationName()
来指定组织名和应用名,然后使用默认的QSettings构造函数:
QCoreApplication::setOrganizationName("MySoft");
QCoreApplication::setOrganizationDomain("mysoft.com");
QCoreApplication::setApplicationName("Star Runner");
...
QSettings settings;
QSettings可以存储一系列设置。每个设置包括指定设置名称(键)的一个字符串和一个与该键关联的QVariant存储数据。使用setValue()可以实现一个设置。例如:
settings.setValue("editor/wrapMargin", 68);
如果存在相同的设置键,现有的值将被新值覆盖。为了提高效率,这些变化可能不会被立即保存到永久存储(可以随时调用sync()来提交更改)。
可以使用value()得到一个设置的值:
int margin = settings.value("editor/wrapMargin").toInt();
如果没有指定键对应的设置,QSettings将会返回一个空QVariant(可转换为整数0)。这时,我们可以通过另一个参数来指定默认值:
int margin = settings.value("editor/wrapMargin", 80).toInt();
void QSettings::beginGroup(const QString & prefix)
为当前组附加前缀。
当前组会自动追加到指定QSettings所有键。此外,查询功能,如childGroups()、childKeys()、allKeys() 也是基于组的。默认情况下,不存在组设置。
组是有用的,以避免输入同样的设置路径。例如:
settings.beginGroup("mainwindow");
settings.setValue("size", win->size());
settings.setValue("fullScreen", win->isFullScreen());
settings.endGroup();
settings.beginGroup("outputpanel");
settings.setValue("visible", panel->isVisible());
settings.endGroup();
这将生成三个设置值:
设置中的键可以包含任何Unicode字符。Windows注册表和INI文件使用对键不区分大小写,而在OS X和iOS的CFPreferences API使用区分大小写。为了避免可移植性问题,需要遵循这些简单的规则:
可以使用’ / ‘字符作为分隔符形成分层键,类似于Unix文件路径。例如:
settings.setValue("mainwindow/size", win->size());
settings.setValue("mainwindow/fullScreen", win->isFullScreen());
settings.setValue("outputpanel/visible", panel->isVisible());
QSettings是可重入的,意味着可以同时在不同的线程中使用不同的QSettings对象,这保证QSettings对象操作同一磁盘上的文件(或在系统注册表中的相同条目)。如果通过QSettings对象修改了一个设置,那么对于操作在同一位置和存在相同的进程的其他QSettings对象来说,更改会立即可见。
QSettings可以由不同的进程(其可以是应用程序同时运行的不同实例或完全不同的应用程序)安全地使用-在相同的系统位置上进行读写,它使用劝告式文件锁和智能合并算法以确保数据的完整性,需要注意的是sync()由其他进程所做的更改。
有时候,想在一个特定的文件或注册表路径中访问存储设置。在所有平台上,如果想直接读取INI文件,可以使QSettings构造函数的第一个参数为文件名,第二个参数为QSettings::IniFormat。例如:
QSettings settings("/home/petra/misc/myapp.ini", QSettings::IniFormat);
然后,就可以对文件进行读写设置。
在OS X和iOS中,可以通过指定第二个参数为QSettings::NativeFormat访问属性列表的.plist文件。例如:
QSettings settings("/Users/petra/misc/myapp.plist", QSettings::NativeFormat);
在Windows中,QSettings可以在系统注册表访问由QSettings写入的设置(或设置支持的格式,如字符串数据)。通过使用一个注册表路径和QSettings::NativeFormat来构建一个QSettings对象。例如:
QSettings settings("HKEY_CURRENT_USER\\Software\\Microsoft\\Office", QSettings::NativeFormat);
所有出现在指定的路径下的注册表条目,可以通过QSettings对象像往常一样进行读写(使用斜杠而不是反斜杠)。例如:
settings.setValue("11.0/Outlook/Security/DontTrustInstalledFiles", 0);
注意,反斜线字符,如前所述,使用QSettings分割为子项。这样一来,不能读写包含斜线或反斜线Windows注册表项,如果需要的话,应该使用Windows API。
在Windows上,有可能存在一个键既有值又存在子键。其默认值是通过使用”Default”或”.” 来代替子键。
settings.setValue("HKEY_CURRENT_USER\\MySoft\\Star Runner\\Galaxy", "Milkyway");
settings.setValue("HKEY_CURRENT_USER\\MySoft\\Star Runner\\Galaxy\\Sun", "OurStar");
settings.value("HKEY_CURRENT_USER\\MySoft\\Star Runner\\Galaxy\\Default"); // returns "Milkyway"