std::remove 和 boost::filesystem::remove 之间的区别?
Posted
技术标签:
【中文标题】std::remove 和 boost::filesystem::remove 之间的区别?【英文标题】:Difference between std::remove and boost::filesystem::remove? 【发布时间】:2018-02-14 09:59:09 【问题描述】:在 C++17 文件系统库中,我们得到了 std::filesystem::remove(path)
,据我了解,它是来自 Boost.Filesystem 的 boost::filesystem::remove(path)
的直接端口。
但 C++ 从 C89 继承了一个非常相似的函数,称为 std::remove(path)
,也记录了从文件系统中删除文件的方法。我隐约意识到这个功能的一些陷阱,例如我相信我听说在 Windows 上 std::remove
不能用于删除当前进程仍处于打开状态的文件。
std::filesystem::remove
是否使用std::remove
解决了这些问题?我应该更喜欢std::filesystem::remove
而不是std::remove
?还是前者只是后者的命名空间同义词,具有相同的缺陷和陷阱?
我的问题标题询问boost::filesystem::remove(path)
和std::remove(path)
之间的区别,因为我认为std::filesystem::remove(path)
可能还没有被很多库供应商实现,但我的理解是它应该基本上是Boost 版本的直接副本。因此,如果您了解 Windows 上的 Boost.Filesystem,您可能也知道足以回答这个问题。
【问题讨论】:
在 Windows 上检查boost::filesystem::remove
的来源需要一分钟才能知道它是 simply calls DeleteFileW
。
filesystem
函数可以处理一般的 Unicode 路径,当您小心时。特别是,对于当前的实现,不要依赖从 UTF-8 的默认转换,而是明确地这样做。旧的std::remove
仅限于狭窄的执行字符集,我真诚地怀疑任何Windows 实现都检测到该执行字符集是UTF-8(因为即使filesystem
实现也无法检测到这一点)。所以在 Windows 中它只能处理来自 Windows ANSI 字符的路径,这是系统特定的编码。
@Cheersandhth.-Alf:Windows C++ 实现如何检测“执行字符集”是 UTF-8?该实现要么定义自己的执行集(不需要检测),要么遵从 Windows(不允许 UTF-8 作为默认字符集)。
@MSalters:UTF-8 产生了非常独特的数据。检查"pøh"
的字节应该足够了。所以对于内联代码的情况来说是微不足道的。
@MSalters:“Windows(不允许 UTF-8 作为默认字符集)”是错误的。 Windows 不支持 UTF-8 语言环境。但是 Windows 的主要编译器 g++ 和 Visual C++ 都支持 UTF-8 作为执行字符集,而 g++ 是默认的。我猜这些编译器的插件替代品,即 clang 和 Intel,行为相同。
【参考方案1】:
检查使用我的 MSVC 安装的标准库源,std::experimental::filesystem::remove
调用其内部的 _Unlink
助手,它简单地调用 _wremove
,它简单地调用 Windows DeleteFileW
。同样,boost::filesystem::remove
在 Windows 上也只是调用 DeleteFileW
。
std::filesystem::remove
is specified by reference to POSIX remove
,但[fs.conform.9945] 中的全局措辞清楚地表明,实现不需要提供确切的 POSIX 行为:
实现应提供如下定义的行为 POSIX。实现应记录任何不同于 POSIX 定义的行为。不支持的实现 确切的 POSIX 行为应该提供接近 POSIX 的行为 考虑到实际操作的限制,行为是合理的 系统和文件系统。如果一个实现不能提供任何合理的行为,则该实现应报告 [fs.err.report] 中指定的错误。 [ 注意:[...]]
实现不需要提供特定文件系统不支持的行为。 [ 示例:[...] ]
::remove
中的任何怪癖(即关于删除的实际行为而不是识别要删除的文件)可能是由于底层 OS API 的限制。我认为没有理由认为在同一操作系统上实现 std::filesystem::remove
会神奇地做得更好。
【讨论】:
Re“我认为没有理由认为 std::filesystem::remove 在同一操作系统上的实现会神奇地做得更好。”,好吧,正如我已经在评论中提到的那样问题,std::filesystem::remove
可以处理一般的 Unicode 路径。这是功能上的很大差异。这意味着std::filesystem::remove
做得更好,更好。
@Cheersandhth.-Alf:检查我的理解——是你的区别,因为std::remove
采用const char*
但fs::remove
采用fs::path
,即Windows 上的basically a basic_string<wchar_t>
?
@Quuxplusone:是的。以上是关于std::remove 和 boost::filesystem::remove 之间的区别?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 std::remove 需要 const 版本的迭代器? [复制]
有没有更好的替代 std::remove_if 从向量中删除元素的方法?
std::remove_if 将“const type”作为“this”参数传递会丢弃 linux 上的限定符 [重复]