【问题标题】:Failed to create a file in windows using createFile API使用 createFile API 在 Windows 中创建文件失败
【发布时间】:2013-12-06 10:28:57
【问题描述】:

我无法使用CreateFile API 在 Windows 中创建文件,GetLastError 返回错误代码 80,这意味着文件存在,但实际上文件不存在。

hFile = CreateFile((LPCTSTR) FILEPATH,  // name of the write 
    GENERIC_READ|GENERIC_WRITE,         // open for writing
    0,                                  // do not share
    NULL,                               // default security 
    CREATE_ALWAYS,                      // create new file only 
    FILE_ATTRIBUTE_NORMAL,              // normal file
    NULL);                              // no attr. template
printf("GET LAST ERROR VALUE IS: %d\n", GetLastError());

我做错了什么?

【问题讨论】:

  • 您能否发布代码显示您如何调用 CreateFile 以及如何获得错误?
  • hFile = CreateFile((LPCTSTR)FILEPATH, // 写入名称 GENERIC_READ|GENERIC_WRITE, // 打开写入 0, // 不共享 NULL, // 默认安全 CREATE_ALWAYS, // 创建仅新文件 FILE_ATTRIBUTE_NORMAL, // 普通文件 NULL); // 没有属性。 template printf("GET LAST ERROR VALUE IS: %d\n", GetLastError());

标签: windows winapi file-io


【解决方案1】:

您的错误检查是错误的。文档说:

返回值

如果函数成功,则返回值是指定文件、设备、命名管道或邮件槽的打开句柄。

如果函数失败,返回值为INVALID_HANDLE_VALUE。要获取更多错误信息,请致电GetLastError

换句话说,失败是由返回值决定的。您不能使用GetLastError 来确定失败。您必须检查返回值并与INVALID_HANDLE_VALUE 进行比较。当你这样做时,我预测你会发现返回值不等于INVALID_HANDLE_VALUE


实际上,即使函数成功,此 API 也会使用最后一个错误值来传达额外信息。

来自CREATE_ALWAYS的文档:

如果指定文件存在且可写,则函数覆盖该文件,函数成功,最后错误代码设置为 ERROR_ALREADY_EXISTS (183)。

并且来自CREATE_NEW的文档:

创建一个新文件,前提是它尚不存在。 如果指定的文件存在,则函数失败,最后一个错误代码设置为 ERROR_FILE_EXISTS (80)。

等等。

您必须牢记的一条黄金法则是,错误检查因功能而异,您必须从头到尾阅读文档。


请注意,我对您的(LPCTSTR) 演员表持怀疑态度。那只是自找麻烦。如果路径是错误的类型,编译器会将您从自己手中拯救出来,除非您使用该强制转换。那个演员只是告诉编译器闭嘴。但在这里它知道得更好。该转换将允许您将 ANSI 文本传递给广泛的 API,反之亦然。你真的应该删除它。

【讨论】:

    【解决方案2】:

    GetLastError 可能会造成麻烦。 注意docs

    "如果函数失败,返回值为INVALID_HANDLE_VALUE。 获取扩展错误信息,调用 GetLastError。”

    所以,首先,如果您从CreateFile 得到和INVALID_HANDLE_VALUE 处理返回,则只调用GetLastError

    其次,最后一个错误代码可以是最后一个错误代码 - 即最近的调用可能没问题,但之前的某些事情失败了:再次来自docs

    "如果函数没有记录设置最后一个错误代码,则返回的值 这个函数只是最近的最后一个错误 已设置的代码;一些函数将最后一个错误代码设置为 0 成功而其他人没有。”

    【讨论】:

    • 这个 API 很特别。错误代码用于指示有关成功的信息。
    • @DavidHeffernan 确实如此。你的回答比我的详细。 +1
    猜你喜欢
    • 2016-07-11
    • 2013-08-31
    • 1970-01-01
    • 1970-01-01
    • 2014-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多