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::removeis 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_extent 可以用来做啥?

为啥 std::remove 需要 const 版本的迭代器? [复制]

有没有更好的替代 std::remove_if 从向量中删除元素的方法?

令人疑惑的 std::remove 算法

std::remove_if 中的 const 参数

std::remove_if 将“const type”作为“this”参数传递会丢弃 linux 上的限定符 [重复]