2011-08-11 29 views
5

一個簡單的問題:C語言文件操作:打開檢查文件指針訪問模式

如何檢查已打開的文件指針的訪問模式?

所以說一個函數傳遞一個已經打開的文件指針:

//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; 
    } 

我會在使用if語句來檢查文件指針什麼作爲已經以只讀方式打開(或不作爲的情況下可能),而不寫入文件,也不依賴於用戶傳遞(可能矛盾)的參數?

系統是windows,code :: blocks編譯器,但是爲了代碼的可移植性,交叉兼容性是首選。

請注意,這不是詢問文件權限,而是FILE指針使用了什麼訪問模式。

自答 [無法單獨回答追加由於用戶權限的限制]:

有由另外的海報一個更好的答案下面,其中包括適當的#define

正如前面建議,看起來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; 
} 

也就是說,當所有的不同的訪問模式的組合與上述功能使用時,產生的輸出:

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 

我很好奇,爲什麼這是從來沒有建議(或從未使用),給定一個交叉兼容的前端功能(簡單地說是一個名稱相同的函數,聲明依賴於平臺)傳遞一個const int來源於因爲FILE指針_flag將是相當簡單和容易解決問題的解決方案。

+0

避免使用oracle來發現程序中已知的內容。一些代碼創建了FILE,該代碼也知道它是如何創建的。給你的函數添加一個參數。 –

+0

事實上,依靠用戶告訴我們一個文件具有什麼樣的訪問權限是不好的形式(如上所述),因爲這是一個安全漏洞。這是編程,而不是預測 - 部分代碼已經知道訪問權限是爲了在使用putc和類似命令時能夠出錯。 – SSight3

+0

不知道爲什麼你認爲用戶與此有任何關係。它需要C程序員將參數傳遞給函數。如果你不相信程序員,那麼所有的投注都關閉。 –

回答

2

警告:這個答案是具體到Visual Studio 2010中


標準輸入輸出。隨Visual Studio 2010的.h文件定義文件類型是這樣的:

struct _iobuf { 
    char *_ptr; 
    int _cnt; 
    char *_base; 
    int _flag; 
    int _file; 
    int _charbuf; 
    int _bufsiz; 
    char *_tmpfname; 
}; 
typedef struct _iobuf FILE; 

當fopening與「RB」模式下的文件,它得到的00000001值。

在fopen函數,一些你interesed的標誌可以被映射爲這樣:

#define _IOREAD   0x0001 
#define _IOWRT   0x0002 
#define _IORW   0x0080 

,底層的文件:

r _IOREAD 
w _IOWRT 
a _IOWRT 
+ _IORW 

這些常量定義在stdio.h描述符包含更多信息,但我還沒有挖掘更多。

+0

由於你的答案包含比我的答案更多的信息(我找不到代碼::塊中的#defines [適用於code :: blocks],但類似的上下文),我會選擇你的。我只會添加前端函數的建議,即在不同的操作系統上使用訪問_file的功能,因此可以重新定義函數來適應。謝謝! – SSight3

1

沒有標準的方法來實現這一點。

+0

訪問FILE指針下的_flag怎麼樣?當然,這包含讀/寫屬性作爲int標誌,並且只需將其與任何預定義數字進行比較就可以找出結果?雖然我確信這可能會被忽略,但我不明白爲什麼不久以來,_flag被視爲一個常量,並在封面下進行處理(當然也可能比尷尬的工作更好)。看起來很奇怪,程序可以知道FILE指針是隻讀的(因此會拒絕寫入),但我作爲程序員不能。 – SSight3

+1

文件是不透明的,你不知道它有哪些成員。 – AProgrammer

+0

只寫類FILE {};並迫使編譯器抱怨先前聲明的FILE實例會揭示它擁有哪些成員。作爲一個定義良好的_iobuf課程,如有必要,可以隨時在線查看。 – SSight3

3

在Linux(及可能所有的UNIX系統)你可以使用fcntl獲得文件的訪問模式:

int get_file_status(FILE* f) { 
    int fd = fileno(f); 
    return fcntl(fd, F_GETFL); 
} 

注意,返回的值是一個整數,像O_RDONLY或標誌的組合O_RDWR,而不是"r""w+"字符串。有些標誌請參閱http://pubs.opengroup.org/onlinepubs/007908799/xsh/open.html

不確定Windows,請參閱On Windows/mingw, what is the equivalent of `fcntl(fd, F_GETFL) | O_ACCMODE`?

+0

你已經鏈接到Windows的問題,似乎是7個月大,並沒有答案。 – SSight3