【问题标题】:C++ Write file to C driveC++ 将文件写入 C 盘
【发布时间】:2018-03-30 00:55:36
【问题描述】:

我的程序让用户指定写入文件的位置。如果他们指定“C:\output.txt”,则文件操作似乎成功(没有错误),但不会创建文件。我知道这是由于 Windows 需要提升权限,并且在以管理员身份运行时它确实写入 C:\。我的问题是如何检测文件实际上没有打开?

即使文件实际上并未创建,此块“成功”且没有错误:

ofstream ofs;
try {
    ofs.open(outputFile);
    if (!ofs.is_open()){
        throw "The file could not be opened";
    }
    ofs << "it worked";
    ofs.close();
} catch (const char* ex){
    cout << ex;
    return 1;
}

【问题讨论】:

  • 如果您没有创建文件的权限,is_open() 应该返回 false。
  • 你确定,文件没有被创建并且仍然让 is_open 变为真吗?试试这个: if ( (ofs.rdstate() & std::ofstream::failbit ) != 0 ) 而不是 ofs.is_open。如果您找到正确的解决方案,请更新。
  • 尝试在文件名中使用正斜杠,例如“C:/outfile.txt”

标签: c++ windows file


【解决方案1】:

如果open() 未能创建/打开文件,则流的is_open() 方法将返回false,并且将设置流的failbit 状态标志,因此fail() 方法和operator! 将返回true :

ofs.open(outputFile);
if (!ofs.is_open())
// or: if (ofs.fail())
// or: if (!ofs)
{
    cout << "The file could not be opened";
    return 1;
}

如果没有报告失败,那么没有失败发生。该文件是在某处创建的,但可能不是您所期望的。

如果您使用相对路径打开文件,则它是相对于调用进程的当前工作目录的,这可能与您的预期不同。所以总是使用绝对路径。

如果您尝试创建文件但无权访问创建文件的文件夹,则文件创建可能会被透明地重定向到用户配置文件中的 VirtualStore 文件夹。

尝试使用SysInternals Process Monitor 来查看在哪里创建文件的确切位置(或者甚至,如果没有访问权限,open() 正在尝试创建文件允许并且不会发生重定向)。


附带说明,您展示的是对异常处理的滥用。如上所示,您根本不需要例外。但是,如果您确实想在失败时引发异常,请考虑改用 ofstream::exceptions() 方法:

ofstream ofs;
ofs.exceptions(ofstream::failbit);
try {
    ofs.open(outputFile);
    ofs << "it worked";
}
catch (std::ios_base::failure &) {
    cout << "The file could not be opened, or written to";
    return 1;
}
ofs.close();

【讨论】:

  • 考虑到观察到的症状,几乎可以肯定是 VirtualStore 重定向,因此您可能需要更多地强调答案的这一部分,并可能举一些例子。
  • 这不是被问到的问题——“我怎样才能检测到文件实际上没有打开?”。我的答案的第一部分解释了如何检查。第二部分解释了如何创建文件 而不是 OP 期望的位置。与所问问题不同。
  • 他已经知道如何判断是否没有打开文件,所以回答这个也没用。解释“没有打开文件”和“文件活动重定向到另一个路径并在那里成功”之间的区别是有帮助的
  • 使用 sysinternals procmon 我能够看到文件输出被重定向到 C:\Users\{user}\AppData\Local\VirtualStore\ - 有没有办法确定文件的实际位置写通知用户?
  • @koga73 不与ofstream ,没有。改用CreateFile(),然后你可以使用GetFinalPathNameByHandle()
猜你喜欢
  • 1970-01-01
  • 2014-05-31
  • 2015-08-09
  • 2023-03-13
  • 1970-01-01
  • 2015-11-23
  • 2020-12-17
  • 2022-01-10
  • 2016-03-02
相关资源
最近更新 更多