在windows上对目录使用fopen

Using fopen on a directory on windows

本文关键字:fopen windows      更新时间:2023-10-16

我试图在打开目录作为文件时从errno中获得正确的错误代码,无论是使用fopen还是使用ifstream.open()。我期望EISDIR,我得到EACCES。

我正在用Windows 7 x64上的MSVC 12.0工具链编译(和执行)。

我一直在文章(https://gehrcke.de/2011/06/reading-files-in-c-using-ifstream-dealing-correctly-with-badbit-failbit-eofbit-and-perror/)中阅读,作者得到了输出"流failbit(或badbit)"。错误状态:Is a directory".

我用GCC 4.6(或更高版本,不确定atm)编译了作者文件,在传递目录作为参数时,我也得到了EACCES。

我知道没有简单的方法来判断一个磁盘对象是否是windows上的目录,所以没有得到EISDIR并不奇怪。

有什么可以做的关于它(获得EISDIR在windows上,也就是说)?是否有其他errno以类似的(意想不到的)方式运行?

微软的C运行时库定义,但不使用EISDIR符号。所以你不会从他们那里得到错误代码。要得到其他问题的答案,您需要查看C库源代码。它与Visual Studio一起发布,如果是Visual Studio 2015或更高版本,还会附带Windows SDK。

在使用通用CRT的Visual Studio 2015(14.0)中,您想要的文件称为errno.cpp,它包含在Windows SDK中,我在c:Program Files (x86)Windows Kits10Source10.0.10586.0ucrtmiscerrno.cpp中有它。

在Visual Studio 2013(12.0)中,你想要的文件被称为dosmap.c,它包含在Visual Studio安装目录的VC子目录中,我在C:Program Files (x86)Microsoft Visual Studio 12.0VCcrtsrcdosmap.c中有它。

这两个文件都包含一个错误表,将操作系统错误码映射到C库错误码。您可以使用它来确认一个特定的映射是否符合您的期望。

fopen函数不是Windows API的一部分;它来自某个给定的C或c++开发环境的运行时支持库。

这个EISDIR错误在为Cygwin构建并随Cygnal一起发布的C应用程序中工作:

c:userskaz>txr
This is the TXR Lisp interactive listener of TXR 148.
Use the :quit command or type Ctrl-D on empty line to exit.
1> (open-file ".")
#<file-stream . 6fffff00738>
2> (get-string *1)
** error reading #<file-stream . 6fffff00738>: 21/"Is a directory"
** during evaluation at expr-2:1 of form (get-string *1)
3>

本语言中的open-file函数使用fopen, get-string最终依赖于C的stdio.h函数。fopen输入成功,但随后的输入尝试收到EISDIR错误。(映射到与Linux和其他平台上相同的传统21代码)。这就变成了一个例外。"Is a directory"字符串来自strerror

您只需要一个功能更丰富的C运行时库,它具有比Microsoft Visual Studio提供的微不足道的POSIX支持更好的功能。