std::filesystem在C++ 17上,std::experimental::filesystem对于许多前C++ 17编译器来说,基于boost::filesystem并且几乎所有它都很明显地移植到较新的std.
但我认为不std::filesystem相同boost::filesystem::unique_path().
我没有注意到std中的等价物吗?或者我是否应该采用一种推荐的方法来模仿实现?
boost::filesystem当我的代码注意到它在支持的平台上进行编译时,我真的希望能够替换依赖std::filesystem,并且unique_path()是我转换中唯一不明显的部分.
为了使用来自C++ 17库的std :: filesystem,我的项目从vs2015迁移到vs2017.
我的项目编译并运行没有错误,包含lib没有错误,但是当尝试使用std :: filesystem时,我得到以下内容:
看来图书馆没有被收录但是为什么不能看到?
编辑:
Microsoft Visual Studio Enterprise 2017
VisualStudio.15.Release/15.7.3+27703.2026
Visual C++ 2017 00369-90000-00000-AA466
Microsoft Visual C++ 2017
从升级当我遇到一个问题#include <experimental/filesystem>来#include <filesystem>.似乎该std::filesystem::path::wstring方法没有返回与中相同的字符串experimental::filesystem.我编写了以下小测试程序,其中包含输出结果.
#include <iostream>
#include <filesystem>
#include <experimental/filesystem>
namespace fs = std::filesystem;
namespace ex = std::experimental::filesystem;
using namespace std;
int main()
{
fs::path p1{ L"C:\\temp/foo" };
wcout << "std::filesystem Native: " << p1.wstring() << " Generic: " << p1.generic_wstring() << endl;
ex::path p2{ L"C:\\temp/foo" };
wcout << "std::experimental::filesystem Native: " << p2.wstring() << " Generic: " << p2.generic_wstring() << endl;
}
/* Output:
std::filesystem Native: C:\temp/foo Generic: C:/temp/foo
std::experimental::filesystem Native: C:\temp\foo …Run Code Online (Sandbox Code Playgroud) 我在Ubuntu 16.04上使用gcc 7.2,我需要使用C++ 17中的新文件系统库.即使确实有一个名为experimental/filesystem的库,我也不能使用它的任何成员.例如,当我尝试编译此文件时:
#include <iostream>
#include <string>
#include <experimental/filesystem>
using namespace std;
namespace fs = std::experimental::filesystem::v1;
int main(){
fs::path p1 = "/usr/share/";
}
Run Code Online (Sandbox Code Playgroud)
我收到一个编译错误,如下所示:
$ g++-7 test.cpp -std=c++17
/tmp/ccfsMnlG.o: In function `std::experimental::filesystem::v1::__cxx11::path::path<char [12], std::experimental::filesystem::v1::__cxx11::path>(char const (&) [12])':
test.cpp:(.text._ZNSt12experimental10filesystem2v17__cxx114pathC2IA12_cS3_EERKT_[_ZNSt12experimental10filesystem2v17__cxx114pathC5IA12_cS3_EERKT_]+0x73): undefined reference to `st
d::experimental::filesystem::v1::__cxx11::path::_M_split_cmpts()'
collect2: error: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?我不认为代码有任何问题,因为我只是从网站上复制粘贴它.我使用的是错误的gcc版本吗?另外,为什么我需要<experimental/filesystem>而不仅仅是<filesystem>在C++ 17中呢?提前致谢.
下面的代码旨在剥离路径的第一部分,以防它存在:
#include <filesystem>
std::filesystem::path strip_prefix(std::filesystem::path p)
{
if (auto it{p.begin()}; it != p.end())
{
++it;
return std::filesystem::path(it, p.end());
}
return p;
}
Run Code Online (Sandbox Code Playgroud)
(见:https://godbolt.org/z/wkXhcw)
我很惊讶地发现这不起作用.代码无法编译,因为路径构造函数只接受迭代字符序列的迭代器.我可以看到使用它,但为什么限制只有那些迭代器的构造?在我看来,不支持从自己的迭代器构造路径是违反直觉的.据我所知,大多数其他STL类型确实支持这个成语.
除了完全重建新路径之外,实现相同目标的有效实现是什么?
更新:在此背景下,我发现以下讨论相关/有趣:http://boost.2283326.n4.nabble.com/boost-filesystem-path-frustration-td4641734.html.我同意戴夫的观点.我认为将路径视为路径元素的容器是一种非常自然的方式来看待它.
可以使用运算符在一行中附加/多个路径:
std::filesystem::path p1{"A"};
auto p2 = p1 / "B" / "C";
Run Code Online (Sandbox Code Playgroud)
这是相当方便的。然而,concat只提供+=:
std::filesystem::path p1{"A"};
auto p2 = p1 / "B" / "C" + ".d"; // NOT OK
Run Code Online (Sandbox Code Playgroud)
这非常烦人,因为我无法轻松地将扩展添加到路径的末尾。我别无选择,只能写一些类似的东西
std::filesystem::path p1{"A"};
auto p2 = p1 / "B" / "C";
p2 += ".d";
Run Code Online (Sandbox Code Playgroud)
我错过了什么吗?这种不一致有原因吗?
关于std::filesystem::is_regular_file(path),cppreference.com说:
\n\n检查给定的文件状态或路径是否对应于常规文件 [\xe2\x80\xa6] 相当于
\ns.type() == file_type::regular.
例如,在Linux内核中,文件类型是在头文件中声明的sys/stat.h。下面列出了每种 Linux 文件类型的类型名称和符号名称:
这个函数在 Windows 上检查什么?
\n例如,考虑一下
file_size.要获取我们将要使用的文件的大小
std::filesystem::path p = std::filesystem::current_path();
// ... usual "does this exist && is this a file" boilerplate
auto n = std::filesystem::file_size(p);
Run Code Online (Sandbox Code Playgroud)
这没有什么不对,如果它是普通的C,但已经被教导C++是一种OO语言[我知道这是多范式,向我们的语言律师道歉:-)]只是感觉如此...... 势在必行(对我来说不好意思,我已经开始期待对象了
auto n = p.file_size();
Run Code Online (Sandbox Code Playgroud)
代替.对于其他功能也是如此,例如resize_file,remove_file甚至可能更多.
你知道为什么Boost std::filesystem选择这种命令式而不是对象式的任何理由吗?有什么好处?提升提到了规则(在最底层),但没有理由.
我正在考虑固有问题,例如ps state after remove_file(p)或错误标志(带有附加参数的重载),但这两种方法都没有解决这些问题.
您可以使用迭代器观察类似的模式,现在我们可以(应该?)begin(it)而不是it.begin(),但在这里我认为理由是更符合非修改next(it)等等.
在我被标记为重复之前,我能找到的所有类似问题在引入 std::filesystem 之前都有答案,并且使用特定于平台的代码或 Boost::filesystem。我正在寻找一个使用 std::filesystem 的便携式答案。
是否可以使用 std::filesystem 获取 C++ 可执行文件所在的路径(而不是工作目录)?如果是的话,怎么样?
我正在尝试将文件的修改时间格式化为字符串 (UTC)。以下代码使用 GCC 8 编译,但不使用 GCC 9。
#include <chrono>
#include <filesystem>
#include <iomanip>
#include <iostream>
#include <sstream>
namespace fs = std::filesystem;
int main() {
fs::file_time_type file_time = fs::last_write_time(__FILE__);
std::time_t tt = decltype(file_time)::clock::to_time_t(file_time);
std::tm *gmt = std::gmtime(&tt);
std::stringstream buffer;
buffer << std::put_time(gmt, "%A, %d %B %Y %H:%M");
std::string formattedFileTime = buffer.str();
std::cout << formattedFileTime << '\n';
}
Run Code Online (Sandbox Code Playgroud)
我使用 C++17 和 C++20 都尝试过decltype(file_time)::clockand std::chrono::file_clock,但它们都不起作用。
$ g++-9 -std=c++2a -Wall -Wextra -lstdc++fs file_time_type.cpp
file_time_type.cpp: In function ‘int main()’:
file_time_type.cpp:12:50: error: ‘to_time_t’ …Run Code Online (Sandbox Code Playgroud)