4

我正在使用 Eclipse Helios、QT 4.6.1 集成插件和 boost 1.52 库开发 C++ 项目。我想从 xml 文件中提取一些信息以使用,我目前正在通过调用 boost function 来实现const read_xml(std::string &, Ptree &, int = 0, const std::locale & = std::locale())

关键是我想避免最终用户从发布文件夹访问该 xml 资源,我不知道该怎么做。是否有任何(简单)方法可以从可执行文件内部处理该 xml 内容,以便将其加载到内存中并继续执行其余过程,就像我已经将 xml 文件视为项目资源一样? 任何提示我都会非常感激。

提前致谢。

4

3 回答 3

2

如果你想防止你的程序的用户修改 XML 文件,你应该使用资源,在可执行文件中编译文件。

如果您已经在使用 Qt,那么请务必查看Qt 4.6 中的 qrc。Qt 提供了一种很好的系统独立方式将资源文件嵌入到可执行文件中。如果您的项目还没有使用 Qt,那么您可能不想为此添加它。

如果您想要 Windows 特定的资源文件,可以查看.rc 文件文档。为了检查编译资源文件中的内容,我过去使用过ResEdit,发现它非常有用。您甚至可以使用它创建资源文件。

如果你的目标是 Mac OS,你可能想看看bundles,这是一个可以放置资源的目录。如果你签署你的应用程序,你可以阻止用户修改包中的任何文件(我不确定是否需要签署它,我在 Mac OS 开发方面没有太多经验)。

如果你的目标是 Linux 或类似的,你可以尝试做这个看起来效果很好的技巧。

所有这些方法的目的只是将你的 XML 文件嵌入到你的可执行文件中,这样你的用户就不能轻易地修改它(好吧,理论上它仍然是可能的,但麻瓜们将无法这样做)。读取文件可能取决于您选择的解决方案。我个人不喜欢 Windows 资源系统,只有在真正需要时才使用它,避免像瘟疫一样使用 Win32 API。如果您选择使用 Qt,阅读文件非常容易,如果您愿意,可以使用 boost 来完成。不是在 处读取文件"resources/config.xml",而是使用 . 指向资源文件":/config.xml"。这里是资源文件:

<!DOCTYPE RCC><RCC version="1.0">
<qresource>
    <file>config.xml</file>
</qresource>
</RCC>

然后当你阅读它时,我不确定你是否必须使用 Qt 类来访问它,但即使你这样做,你也可以使用QFile和调用打开文件readAll,然后使用 boost 的结果:

QFile myConfigFile(":/config.xml");
if (!myConfigFile.open(QIODevice::ReadOnly | QIODevice::Text))
     return;
read_xml(QString(myConfigFile.readAll()), [...]);

我还没有测试过它,但它应该可以与类似的东西一起使用。

于 2013-06-03T18:19:02.380 回答
1

read_xml是超载的。您可能指的是此功能:

read_xml(文件名...)

但也有

read_xml(流...)

stream以任何方式产生的任何std::istream对象在哪里。您甚至可以将源中的硬编码字符串转换为流。

于 2013-06-03T18:12:41.980 回答
1

再次感谢您的提示 Uflex。我的应用程序的重点是使用 QT,但仅用于 GUI 功能,避免在下面的应用程序控制器中使用它......

我刚刚检查了您的方法,除了最后一行之外,它主要是我正在寻找的,因为 read_xml 函数接受带有 xml 文件路径的字符串或带有该 xml 内容的字符串流。因此,在将您的解释与这两个链接相结合后:

如何为 Boost.PropertyTree 提供字符串而不是文件?

http://doc.qt.digia.com/4.6/resources.html

我们准备好了……

istringstream ss;
QFile file (QString::fromStdString(pathString));
if(file.open(QIODevice::ReadOnly | QIODevice::Text)){
    ss.str(QString(file.readAll()).toStdString());
    read_xml(ss, ...)
    ...
}
于 2013-06-06T13:37:20.783 回答