我如何“正常化”使用 boost::filesystem 的路径名?
我们在应用程序中使用 boost::filesystem。我有一个“完整”路径,它是通过将多个路径连接在一起构建的:
#include <boost/filesystem/operations.hpp>
#include <iostream>
namespace bf = boost::filesystem;
int main()
{
bf::path root("c:\\some\\deep\\application\\folder");
bf::path subdir("..\\configuration\\instance");
bf::path cfgfile("..\\instance\\myfile.cfg");
bf::path final ( root / subdir / cfgfile);
cout << final.file_string();
}
最终路径打印为:
c:\some\deep\application\folder\..\configuration\instance\..\instance\myfile.cfg
这是一个有效的路径,但当我将其显示给用户时,我希望将其标准化。< /em> (注意:我什至不确定“标准化”是否是正确的词)。像这样:
c:\some\deep\application\configuration\instance\myfile.cfg
早期版本的 Boost 有一个 normalize()
函数 - 但它似乎已被弃用并删除(没有任何解释)。
我是否有理由不应该使用 BOOST_FILESYSTEM_NO_DEPRECATED
宏?是否有其他方法可以使用 Boost Filesystem 库来执行此操作?或者我应该编写代码来直接将路径作为字符串进行操作?
We are using boost::filesystem in our application. I have a 'full' path that is constructed by concatenating several paths together:
#include <boost/filesystem/operations.hpp>
#include <iostream>
namespace bf = boost::filesystem;
int main()
{
bf::path root("c:\\some\\deep\\application\\folder");
bf::path subdir("..\\configuration\\instance");
bf::path cfgfile("..\\instance\\myfile.cfg");
bf::path final ( root / subdir / cfgfile);
cout << final.file_string();
}
The final path is printed as:
c:\some\deep\application\folder\..\configuration\instance\..\instance\myfile.cfg
This is a valid path, but when I display it to the user I'd prefer it to be normalized. (Note: I'm not even sure if "normalized" is the correct word for this). Like this:
c:\some\deep\application\configuration\instance\myfile.cfg
Earlier versions of Boost had a normalize()
function - but it seems to have been deprecated and removed (without any explanation).
Is there a reason I should not use the BOOST_FILESYSTEM_NO_DEPRECATED
macro? Is there an alternative way to do this with the Boost Filesystem library? Or should I write code to directly manipulating the path as a string?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
Boost v1.48 及更高版本
您可以使用
boost::filesystem::canonical
:http://www.boost.org/doc/libs/1_48_0/libs/filesystem/v3/doc/reference.html#canonical
v1。 48 及以上版本还提供了用于解析符号链接的 boost::filesystem::read_symlink 函数。
v1.48 之前的 Boost 版本
正如其他答案中提到的,您无法标准化,因为 boost::filesystem 无法遵循符号链接。但是,您可以编写一个“尽可能”规范化的函数(假设“.”和“..”被正常处理),因为 boost 提供了确定文件是否是符号链接的能力。
也就是说,如果“..”的父级是符号链接,那么您必须保留它,否则删除它可能是安全的,并且删除“.”可能总是安全的。
它与操作实际的字符串类似,但稍微优雅一些。
Boost v1.48 and above
You can use
boost::filesystem::canonical
:http://www.boost.org/doc/libs/1_48_0/libs/filesystem/v3/doc/reference.html#canonical
v1.48 and above also provide the
boost::filesystem::read_symlink
function for resolving symbolic links.Boost versions prior to v1.48
As mentioned in other answers, you can't normalise because boost::filesystem can't follow symbolic links. However, you can write a function that normalises "as much as possible" (assuming "." and ".." are treated normally) because boost offers the ability to determine whether or not a file is a symbolic link.
That is to say, if the parent of the ".." is a symbolic link then you have to retain it, otherwise it is probably safe to drop it and it's probably always safe to remove ".".
It's similar to manipulating the actual string, but slightly more elegant.
使用
boost::filesystem
版本 3,您还可以尝试通过调用canonical
来删除所有符号链接。这只能针对现有路径完成,因此也适用于不存在路径的函数需要两个步骤(在 MacOS Lion 上进行测试,并根据 @void.pointer 的评论针对 Windows 进行更新):With version 3 of
boost::filesystem
you can also try to remove all the symbolic links with a call tocanonical
. This can be done only for existing paths so a function that also works for non-existing ones would require two steps (tested on MacOS Lion and updated for Windows thanks to @void.pointer's comment):您对
canonical
的投诉和/或愿望已由 Boost 1.60 解决 [1] 与Your complaints and/or wishes about
canonical
have been addressed by Boost 1.60 [1] with解释位于 http://www.boost.org /doc/libs/1_40_0/libs/filesystem/doc/design.htm :
其中适用于删除
normalize
的“现实”是:如果不访问底层文件系统,库就无法真正标准化路径,这使得操作 a) 不可靠 b) 不可预测 c) 错误 d) 以上所有
the explanation is at http://www.boost.org/doc/libs/1_40_0/libs/filesystem/doc/design.htm :
where the "reality" applicable to removal of
normalize
is:the library cannot really normalize a path without access to the underlying filesystems, which makes the operation a) unreliable b) unpredictable c) wrong d) all of the above
它还在那里。继续使用它。
我想他们不赞成它,因为符号链接意味着折叠的路径不一定是等效的。如果
c:\full\path
是c:\rough
的符号链接,那么c:\full\path\..
将是<代码>c:\,而不是c:\full
。It's still there. Keep using it.
I imagine they deprecated it because symbolic links mean that the collapsed path isn't necessarily equivalent. If
c:\full\path
were a symlink toc:\rough
, thenc:\full\path\..
would bec:\
, notc:\full
.由于“规范”函数仅适用于存在的路径,因此我制定了自己的解决方案,将路径拆分为各个部分,并将每个部分与下一个部分进行比较。我将其与 Boost 1.55 一起使用。
要使用它,这里有一个关于如何调用它的示例:
Since the "canonical" function works only with paths that exist, I made my own solution that splits the path to its parts, and compares every part with the next one. I'm using this with Boost 1.55.
To use this, here's an example on how you call it: