Mik*_*kes 36 c++ filesystems boost
我们在应用程序中使用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();
}
Run Code Online (Sandbox Code Playgroud)
最终路径打印为:
c:\some\deep\application\folder\..\configuration\instance\..\instance\myfile.cfg
Run Code Online (Sandbox Code Playgroud)
这是一个有效的路径,但是当我向用户显示它时,我更喜欢它被规范化.(注意:我甚至不确定"标准化"是否是正确的词).像这样:
c:\some\deep\application\configuration\instance\myfile.cfg
Run Code Online (Sandbox Code Playgroud)
早期版本的Boost有一个normalize()功能 - 但它似乎已被弃用和删除(没有任何解释).
有没有理由我不应该使用BOOST_FILESYSTEM_NO_DEPRECATED宏?有没有其他方法可以使用Boost Filesystem库执行此操作?或者我应该编写代码来直接将路径作为字符串操作?
Ada*_*wen 30
你可以使用boost::filesystem::canonical:
path canonical(const path& p, const path& base = current_path());
path canonical(const path& p, system::error_code& ec);
path canonical(const path& p, const path& base, system::error_code& ec);
Run Code Online (Sandbox Code Playgroud)
http://www.boost.org/doc/libs/1_48_0/libs/filesystem/v3/doc/reference.html#canonical
v1.48及以上版本还提供了boost::filesystem::read_symlink解析符号链接的功能.
正如其他答案中所提到的,您无法规范化,因为boost :: filesystem不能遵循符号链接.但是,您可以编写一个"尽可能"标准化的函数(假设"."和".."被正常处理),因为boost提供了确定文件是否为符号链接的能力.
也就是说,如果".."的父级是符号链接,那么你必须保留它,否则放弃它可能是安全的,删除"."可能总是安全的.
它类似于操纵实际的字符串,但稍微更优雅.
boost::filesystem::path resolve(
const boost::filesystem::path& p,
const boost::filesystem::path& base = boost::filesystem::current_path())
{
boost::filesystem::path abs_p = boost::filesystem::absolute(p,base);
boost::filesystem::path result;
for(boost::filesystem::path::iterator it=abs_p.begin();
it!=abs_p.end();
++it)
{
if(*it == "..")
{
// /a/b/.. is not necessarily /a if b is a symbolic link
if(boost::filesystem::is_symlink(result) )
result /= *it;
// /a/b/../.. is not /a/b/.. under most circumstances
// We can end up with ..s in our result because of symbolic links
else if(result.filename() == "..")
result /= *it;
// Otherwise it should be safe to resolve the parent
else
result = result.parent_path();
}
else if(*it == ".")
{
// Ignore
}
else
{
// Just cat other path entries
result /= *it;
}
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
jar*_*zec 19
使用版本3,boost::filesystem您还可以尝试通过调用删除所有符号链接canonical.这只能对现有路径执行,因此适用于不存在路径的功能需要两个步骤(在MacOS Lion上测试):
boost::filesystem::path normalize(const boost::filesystem::path &path) {
boost::filesystem::path absPath = absolute(path);
boost::filesystem::path::iterator it = absPath.begin();
boost::filesystem::path result = *it++;
// Get canonical version of the existing part
for (; exists(result / *it) && it != absPath.end(); ++it) {
result /= *it;
}
result = canonical(result);
// For the rest remove ".." and "." in a path with no symlinks
for (; it != absPath.end(); ++it) {
// Just move back on ../
if (*it == "..") {
result = result.parent_path();
}
// Ignore "."
else if (*it != ".") {
// Just cat other path entries
result /= *it;
}
}
// Make sure the dir separators are correct even on Windows
return result.make_prefered();
}
Run Code Online (Sandbox Code Playgroud)
Ale*_*aev 12
您的投诉和/或愿望canonical已由Boost 1.60 [ 1 ]解决
path lexically_normal(const path& p);
Run Code Online (Sandbox Code Playgroud)
解释见http://www.boost.org/doc/libs/1_40_0/libs/filesystem/doc/design.htm:
在下面描述的现实中工作.
理由:这不是一个研究项目.需要的是适用于当今平台的东西,包括一些具有有限文件系统的嵌入式操作系统.由于强调可移植性,如果标准化,这样的库将更有用.这意味着能够使用更广泛的平台,只有Unix或Windows及其克隆.
适用于移除的"现实" normalize是:
符号链接导致某些路径的规范和普通形式表示不同的文件或目录.例如,给定目录层次结构/ a/b/c,在/名为x的符号链接指向b/c,然后在POSIX路径名解析规则下,路径"/ a/x/.."应解析为"/ A/b".如果"/ a/x/.."首先标准化为"/ a",则会错误地解析.(案例由Walter Landry提供.)
库无法真正规范化路径而无法访问底层文件系统,这使得操作a)不可靠b)不可预测c)错误d)以上所有
| 归档时间: |
|
| 查看次数: |
26197 次 |
| 最近记录: |