【问题标题】:C++ ofstream equivalent to Win32 CreateFile with CREATE_NEWC++ ofstream 等效于带有 CREATE_NEW 的 Win32 CreateFile
【发布时间】:2015-02-26 16:50:19
【问题描述】:

在应用程序中,我想确定我正在编写一个全新的(二进制)文件。在 Win32 编程中,我知道我可以通过 CreateFile 使用 CREATE_NEW 来做到这一点,但我无法制定出纯 C++ 标准方式。

创建一个新文件,前提是它不存在。
如果指定的文件存在,则函数失败,最后一个错误代码设置为 ERROR_FILE_EXISTS (80)。
如果指定的文件不存在并且是可写位置的有效路径,则会创建一个新文件。

我尝试使用std::ios::out | std::ios::binary | std::ios::ate,然后查看tellp 是否给了我文件的开头,但除了这仍然会覆盖一个空文件的明显情况之外,它似乎还截断了一个非空文件反正我用std::ios::trunc...

这是在 VS2013 上,虽然我认为这不是编译器/库错误。

【问题讨论】:

  • iostream 用户在过去的 16 年里一直在纠结这个问题,可能是首先尝试打开文件以检查它是否已经存在。与 CRT 最接近的是带有 _O_CREAT 和 _O_EXCL 模式标志的 _open()。

标签: c++ file file-io io fstream


【解决方案1】:

C++ 标准没有保证新文件的 API。当以只写模式打开现有文件而不指定std::ios_base::app 时,它会被截断(与是否使用std::ios_base::trunc 无关)。我不了解 Windows,但在 POSIX 上,这将保留原始 inode,并且已经打开文件的进程仍然可以访问它。

如果获得一个打开的空文件而不是一个新文件就足够了,那么省略 std::ios_base::instd::ios_base::app 应该可以解决问题(请注意,打开 std::fstreamstd::ifstream 会隐式添加 std::ios_base::in )。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-11
    • 1970-01-01
    • 1970-01-01
    • 2020-10-23
    • 1970-01-01
    • 1970-01-01
    • 2021-05-04
    • 1970-01-01
    相关资源
    最近更新 更多