C++替换 ios::noreplace

发布于 2025-01-05 00:52:18 字数 397 浏览 3 评论 0原文

我正在使用 fstream 打开文件进行写入。我不想覆盖现有文件,因此经过一番搜索后,我发现了 ios::noreplace。但是当我编译这个时:

#include <fstream>
using namespace std;
//......Did something else.
ofstream fout;
fout.open(outputFile,ios::noreplace);//outputFile is a C string

我收到一个错误

 error: ‘noreplace’ is not a member of ‘std::ios’

我只是想知道是否有 ios::noreplace 的 std:: 替代品?

I'm using fstream to open a file for write. I don't want to overwrite an existing file so after some searching, I found ios::noreplace. But when I compile this:

#include <fstream>
using namespace std;
//......Did something else.
ofstream fout;
fout.open(outputFile,ios::noreplace);//outputFile is a C string

I get an error

 error: ‘noreplace’ is not a member of ‘std::ios’

I'm just wondering is there any std:: subsitution for ios::noreplace?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

静赏你的温柔 2025-01-12 00:52:18

在互联网上的一些搜索表明,您可以通过尝试以“输入”模式打开来手动添加存在检查:

std::fstream myfile("thefile.txt", std::ios::in);

if (myfile)
{
    // error, file exists!
}
else
{
    myfile.close();
    myfile.open("thefile.txt", std::ios::out);  // OK now
}

Some searching on the internet reveals that you can add an existence check manually by attempting to open in "input" mode:

std::fstream myfile("thefile.txt", std::ios::in);

if (myfile)
{
    // error, file exists!
}
else
{
    myfile.close();
    myfile.open("thefile.txt", std::ios::out);  // OK now
}
凡间太子 2025-01-12 00:52:18

投诉已得到解决! C++23 最终标准化了 std::ios_base::noreplace 标志来打开文件以独占模式进行写入,即如果该文件已存在则失败。

论文:https://www.open-std .org/jtc1/sc22/wg21/docs/papers/2022/p2467r1.html

通用标准库实现已经支持这一点C++23 模式,包括与 GCC/g++ 捆绑在一起的 libstdc++

The complaints are addressed! C++23 finally standardises the std::ios_base::noreplace flag to open a file for writing in exclusive mode, i.e. to fail if that file already exists.

Paper: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2467r1.html

Common standard library implementations are already supporting this in C++23 mode, including libstdc++ as bundled with GCC/g++.

只是我以为 2025-01-12 00:52:18

建议的答案是有风险的,因为它们有竞争条件。
除非您可以保证在运行此测试时没有人会创建该文件,否则您不应该使用它。

作为解决方法,请使用不可移植的方法(例如在 Linux 上使用 O_CREAT|O_EXCL 打开)。

您可以使用生成的句柄和像 boost 这样的代码将其包装到 ofstream 中,或者在这种情况下使用 open() 仅检查文件,然后在文件上创建一个新的 ofstream (后者假设没有人删除/重命名该文件 -之间,因此可能仍然存在竞争条件)。

C++ 不提供任何安全的方式来创建文件是一个糟糕的笑话,并且可能是导致相当多安全漏洞的原因。您必须喜欢那些鼓励不良实践、使编写正确代码变得不可能的标准。

The suggested answers are risky since they have race conditions.
Unless you can guarantee nobody will ever create that file while your are running this test, you should not use it.

As a workaround, use the non-portable method (on Linux for example open with O_CREAT|O_EXCL).

You can either use the resulting handle with code like boost to wrap it into an ofstream, or in this case use open() only to check and then create a new ofstream on the file (the latter assumes nobody deletes/renames the file in-between and thus might still have a race condition).

C++ not providing ANY safe way to create a file is a bad joke and likely the cause of quite a few security holes. You have to love standards that encourage bad practices by making writing correct code impossible.

ら栖息 2025-01-12 00:52:18

noreplace 从未进入标准。谷歌搜索大约四秒的结果:
http://www.devx.com/tips/Tip/14544

在准标准 C++ 中,某些实现提供了 ios::nocreate 和 ios::noreplace 标志来控制文件创建。这些标志过于特定于平台,从未进入标准库,它取代了已弃用的预标准标头。但是,您可以相当轻松地实现这些过时标志的功能。

fstream fs(fname, ios_base::in);// attempt open for read
if (!fs)
{
    // file doesn't exist; create a new one
    fs.open(fname, ios_base::out);
}
else //ok, file exists; close and reopen in write mode
{
     // Should throw an error
}

noreplace never got into the standard. About four seconds of googling yields:
http://www.devx.com/tips/Tip/14544

In pre-standard C++, certain implementations of offered the flags ios::nocreate and ios::noreplace for controlling file creation. These flags were too platform-specific and never made it into the standard library, which supersedes the deprecated, pre-standard header. However, you can achieve the functionality of these obsolete flags rather easily.

fstream fs(fname, ios_base::in);// attempt open for read
if (!fs)
{
    // file doesn't exist; create a new one
    fs.open(fname, ios_base::out);
}
else //ok, file exists; close and reopen in write mode
{
     // Should throw an error
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文