最近寫代碼,遇到很多地方需要判斷檔案是否存在的。網上的方法也是千奇百怪,“百家争鳴”。
fopen方式打開的比較多見,也有其他各種方式判斷檔案是否存在的,由于其他方法與本文無關,是以不打算提及。
筆者近來使用winapi比較多,于是順便搜尋了msdn,找到了一個函數:PathFileExists
BOOL PathFileExists(
_In_ LPCTSTR pszPath
);
以下是筆者最初的方法,windows api原則上提供的函數應該是最合理高效的,起碼這個方法在windows平台上來說有足夠的官腔味。
/*Minimum supported client: Windows 2000 Professional, Windows XP [desktop apps only]
Minimum supported server: Windows 2000 Server [desktop apps only]
DLL: Shlwapi.dll (version 4.71 or later)
*/
#include <Windows.h> //Windows API FindFirstFile
#include <Shlwapi.h> //Windows API PathFileExists
#pragma comment(lib, "shlwapi.lib")
int main(void)
{
if(PathFileExists("setting.ini")){
printf("load custom setting...\n");
}else{
printf("setting file missing,load default..\n");
}
return 0;
}
群裡有朋友提起fopen是posix系統中打開檔案fd的标準open接口。筆者也曾疑慮,如果一個檔案幾十個G,會不會在fopen的過程中占用很多資源,
後來求證得到的回複:
肯定不會加載啊
正如你說的,如果檔案 xxxG 怎麼辦
檔案是用指針通路的,是以不用擔心你的問題
由于筆者目前研究範圍和能力有限,沒去研究。
筆者的程式有時候需要相容linux,通常會在cygwin下面編譯并測試,也是再三覺得,過于依賴于特定作業系統的api有點不妥。
在google上搜尋了了一下,stackoverflow給出了一個答案:
What's the best way to check if a file exists in C? (cross platform)
使用函數
int __cdecl access(const char *, int);
筆者常用的tcc,Visual c++ 6.0,gcc 打開tcc-win32-0.9.26檢視相關引用頭檔案時發現unistd.h隻是簡單的#include了一次io.h
#include <stdio.h>
#if defined(WIN32) || defined(_WIN32) || defined(WIN64)|| defined(_WIN64)
#include <io.h>
#ifndef F_OK
#define F_OK 0 /* Check for file existence */
#endif
#endif
#if defined(__CYGWIN__)|| defined(__linux__)|| defined(linux) || defined(__linux)
#include <unistd.h>
#endif
int main(void)
{
if( access( "setting.ini", F_OK ) != -1 ) {
printf("load custom setting...\n");
} else {
printf("setting file missing,load default..\n");
}
}