C文件操作:检查打开的文件指针访问模式

SSi*_*ht3 6 c

一个简单的问题:

如何检查已打开文件指针的访问模式?

所以说一个函数传递已经打开的FILE指针:

    //Pseudo code
    bool PseudoFunction(FILE *Ptr)
    {
        if( ... Insert check for read-only access rights )
        {
            //It's read only access mode
            return true;
        }
       //File pointer is not read-only and thus write operations are permitted
       return false;
    }
Run Code Online (Sandbox Code Playgroud)

我将在if语句中使用什么来检查FILE指针是否为只读(或不是,视情况而定),而不是写入文件,而不依赖于用户传递(可能是矛盾的)参数?

系统是windows,code :: blocks编译器,但为了代码的可移植性,交叉兼容性是首选.

注意,这不是询问文件权限,而是FILE指针使用了什么访问模式.

SELF-ANSWER [由于用户权限限制,无法附加单独的答案]:

下面的另一张海报有一个更好的答案,包括正确的#defines

如前所述,看起来FILE指针的_flag(在_iobuf下定义)是知道文件是否只读的关键.您的里程可能会有所不同,但相同的基本概念应该很容易适应,示例代码:

#define READ_ONLY_FLAG 1

bool PrintFlagPtr(const char FileName[], const char AccessMode[])
{
    FILE *Ptr = NULL;
    Ptr = fopen(FileName,AccessMode);
    printf("%s: %d ",AccessMode,Ptr->_flag);

    int IsReadOnly = Ptr->_flag;
    fclose(Ptr);
    Ptr = NULL;


    if( (IsReadOnly&READ_ONLY_FLAG) == READ_ONLY_FLAG )
    {
        printf("File is read only!\n");
        return true;
    }

    printf("\n");
    return false;
}
Run Code Online (Sandbox Code Playgroud)

当所有不同的访问模式组合与上述功能一起使用时,产生以下输出:

Output:
w: 2
r: 1 File is read only!
a: 2
wb: 2
rb: 1 File is read only!
ab: 2
w+: 128
r+: 128
a+: 128
w+b: 128
r+b: 128
a+b: 128
Run Code Online (Sandbox Code Playgroud)

我很好奇为什么从未建议(或从未使用过),给定交叉兼容的前端函数(只是一个具有相同名称的函数,声明取决于平台)传递来自给定FILE指针的const int _flag将是解决问题的简单易行的解决方案.

ken*_*ytm 7

在 Linux(可能还有所有 UNIX 系统)上,您可以fcntl用来获取文件的访问模式:

int get_file_status(FILE* f) {
    int fd = fileno(f);
    return fcntl(fd, F_GETFL);
}
Run Code Online (Sandbox Code Playgroud)

请注意,返回值是作为标志组合的整数,例如O_RDONLYor O_RDWR,而不是"r"or"w+"字符串。有关其中一些标志,请参阅http://pubs.opengroup.org/onlinepubs/007908799/xsh/open.html

不确定 Windows,请参阅在 Windows/mingw 上,`fcntl(fd, F_GETFL) 的等价物是什么 | O_ACCMODE`?.


Sir*_*ius 2

警告:此答案特定于 Visual Studio 2010。


Visual Studio 2010 附带的 stdio.h 文件定义 FILE 类型如下:

struct _iobuf {
    char *_ptr;
    int   _cnt;
    char *_base;
    int   _flag;
    int   _file;
    int   _charbuf;
    int   _bufsiz;
    char *_tmpfname;
};
typedef struct _iobuf FILE;
Run Code Online (Sandbox Code Playgroud)

当使用“rb”模式打开文件时,它得到的值为0x00000001。

在 fopen 函数中,您感兴趣的一些标志可以映射如下:

r    _IOREAD
w    _IOWRT
a    _IOWRT
+    _IORW
Run Code Online (Sandbox Code Playgroud)

这些常量在 stdio.h 中定义:

#define _IOREAD         0x0001
#define _IOWRT          0x0002
#define _IORW           0x0080
Run Code Online (Sandbox Code Playgroud)

底层文件描述符包含更多信息,我还没有进一步挖掘。