文件流在不存在的文件上进行读写操作

10

是否有可能在文件不存在的情况下使用ios::in和ios::out打开fstream,而不会出现错误?


5
不要忘记接受答案,或者通过告诉回答者你是否尝试过他们的解决方案(或提供更多细节,以便他们可以量身定制答案)来帮助回答者。 - Matt Curtis
5个回答

11
为了在不存在的文件上打开一个fstream,并且不会出现错误地进行输入和输出(随机访问),你应该在open(或构造函数)调用中提供flags fstream::in | fstream::out | fstream::trunc。由于文件不存在,将文件截断为零字节是没有问题的。
当指定ios::in时,您可能希望在打开不存在的文件时出现错误,因为您永远无法从流中读取,因此在这种情况下尽早失败将防止意外故障。

1
那么为什么通过 fstream 类的对象打开一个不存在的文件不会抛出错误呢?例如:fstream myfile; myfile.open("this_file_doesn't_exist.txt"); //这不会抛出任何错误。 - Ketcomp

4
很遗憾,回答您的问题是:“不”,这不可能在单个C++语句中完成。是的,很多人会回答说,你可以使用组合标志"fstream::in | fstream::out | fstream::trunc"。但那个答案是无意义的。 "fstream::trunc" 的意思是,打开输出文件时将把文件截断为大小零。但是,为什么你想要打开一个空文件进行读写呢?除了极少数情况下需要一个文件作为应用程序数据的临时存储器,你首先要编写并稍后再次读取,否则没有使用该标志组合的用途。
一些人建议首先尝试用 "fstream::in | fstream::out"(以及可能需要的进一步标志,如 "fstream:app" 或 "fstream::binary"),然后检查文件的错误状态:如果无法打开文件,则重新尝试包括“| fstream::trunc”的打开操作。然而,这种解决方案有几个警告。例如,如果您的文件系统通过NFS挂载,则尝试以读/写模式打开文件的第一次尝试可能会由于暂时的网络问题而失败。如果第二次尝试(包括 "fstream::trunc" 标志)成功,那么你之前收集的数据就没了。
安全的解决方案是首先仅打开文件以进行追加(如果文件不存在,则会创建该文件,但不会将其截断),然后立即关闭该文件并第二次以读写模式打开它。这可以通过以下代码实现:请注意,首先构造一个 "ofstream",然后立即丢弃它。
std::string filename { "test.txt" };
(void) std::ofstream(filename, std::ostream::app);
std::fstream file(filename);

或者,如果您需要更多的标志,例如 binary,请使用:

std::string filename { "test.txt" };
(void) std::ofstream(filename, std::ofstream::app | std::fstream::binary);
std::fstream file(filename, std::fstream::in | std::fstream::out | std::fstream::binary);

我希望在 C++25(或者是下一个标准)中,他们能够添加一个标志 std::fstream::create,用于在请求读写模式时创建不存在的输出文件。

当我需要在打开文件之前仅在文件不存在时创建文件时,这个功能运行得很正确。 - netcat

1
#include <fstream> 

ofstream out("test", ios::out);
if(!out)
{
    cout << "Error opening file.\n";
    return 1;
}

ifstream in("test", ios::in);
if(!in)
{
    cout << "Error opening file.\n";
    return 1;
}

如果发生错误,将显示消息并返回 1。但是,可以仅编译和执行 ofstream out("test", ios::out);ifstream in("test", ios::in); 而不出现任何错误。无论哪种方式,都会创建文件 test


0
std::fstream f("test.txt", std::ios_base::out);
f.close(); //file now exists always
f.open("test.txt", fstream::in | std::ios_base::out);
//f is open for read and write without error

我还没有检查过以确保它能够无误地打开,但我相信它应该是可以的。


0
#include <iostream>
#include <fstream>
using namespace std;

int main () {
  fstream f("test.txt", fstream::in | fstream::out);
  cout << f.fail() << endl;
  f << "hello" << endl;
  f.close();    
  return 0;
}

如果文件不存在,此代码将打印1并不会创建"test.txt"文件。因此,在没有出现错误的情况下,无法打开和使用fstream读取不存在的文件。


你是不是想说 "filestr.fail()" 和 "filestr << "hello" << endl;"?! - Secko

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接