boost::filesystem::rename:当文件已存在时无法创建该文件
我正在使用 boost::filesystem 重命名文件,有时目标文件会存在。根据此处的Boost文档:
http://www.boost.org/doc/libs/1_42_0/libs/filesystem/doc/reference.html#Non-member-functions
模板 void 重命名(const Path1& from_p, const 路径2&顶部);要求: Path1::external_string_type 和 Path2::external_string_type 是 相同类型。
效果:将 from_p 重命名为 to_p,就好像 通过 POSIX rename()。
后置条件:!exists(from_p) && 存在(to_p),并且内容和 文件原来的属性 命名为 from_p 的其他方面保持不变。
[注意:如果 from_p 和 to_p 解析为 相同的文件,不采取任何操作。 否则,如果 to_p 解析为 现有文件,则将其删除。一个 符号链接本身被重命名, 而不是它解析为的文件 被更名。 -- 尾注]
(我的重点)
在 XP SP3 上测试通过 MS Visual Studio 2008 编译的代码时,重命名会抛出 boost::filesystem::filesystem_error 并显示消息:
当该文件已存在时无法创建文件
我注意到这有在错误报告中提出: https://svn.boost.org/trac/boost/ticket/2866
...但声称在 Boost 1.41.0 中关闭,而我正在使用 Boost 1.42.0。
我在这里做错了什么还是应该恢复到 std::rename ?
我还没有在 Linux 上测试过,所以不知道问题是否也存在。
I'm renaming a file using boost::filesystem, and sometimes the target file will exist. According to the boost documentation here:
http://www.boost.org/doc/libs/1_42_0/libs/filesystem/doc/reference.html#Non-member-functions
template
void rename(const Path1& from_p, const
Path2& to_p); Requires:
Path1::external_string_type and
Path2::external_string_type are the
same type.Effects: Renames from_p to to_p, as if
by POSIX rename().Postconditions: !exists(from_p) &&
exists(to_p), and the contents and
attributes of the file originally
named from_p are otherwise unchanged.[Note: If from_p and to_p resolve to
the same file, no action is taken.
Otherwise, if to_p resolves to an
existing file, it is removed. A
symbolic link is itself renamed,
rather than the file it resolves to
being renamed. -- end note]
(my emphasis)
When testing this code compiled via MS Visual Studio 2008 on XP SP3, the rename throws boost::filesystem::filesystem_error with the message:
Cannot create a file when that file already exists
I note this has been raised in a bug report:
https://svn.boost.org/trac/boost/ticket/2866
... but claims to be closed in Boost 1.41.0 and I'm using Boost 1.42.0.
Am I doing something wrong here or should I just revert to std::rename?
I haven't tested this on Linux yet so don't know if the problem exists there too.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
看起来它已被修复,但仅限于 Boost.Filesystem 的沙盒“V3”版本,该版本尚未包含在主线 Boost 版本中。
我在 Linux 上的 Boost 1.43.0 上进行了测试,得到了相同的结果 - 事实上,错误报告指出了有问题的代码,该代码显式检查 POSIX 上是否存在并抛出异常。最初这样做可能是因为 Windows 上的
MoveFile
表现出相同的行为?在沙箱 V3 版本中,重命名将在 Windows 上调用MoveFileEx
和 POSIX 上的std::rename
,并允许覆盖现有文件。我想您可以通过在调用
boost::filesystem::rename
之前在目标上调用boost::filesystem::remove
来解决这个问题,具体取决于您的程序是否需要操作是否是原子的。Looks like it was fixed, but only in the sandbox "V3" version of Boost.Filesystem, which is not in the mainline Boost releases yet.
I tested on Boost 1.43.0 on Linux with the same results - in fact the bug report points out the offending code, which explicitly checks for existence on POSIX and throws the exception. It's possible this was done originally because
MoveFile
on Windows exhibits the same behavior? In the sandbox V3 version, rename will callMoveFileEx
on Windows andstd::rename
on POSIX, and allows overwriting an existing file.I suppose you could work around it by calling
boost::filesystem::remove
on the target before callingboost::filesystem::rename
, depending upon whether your program needs the operation to be atomic or not.