2017-02-04 74 views
0

我的基本問題是,這段代碼幾乎總是會拋出異常:可移植性測試C++中的文件夾?

bool DirectoryRange::isDirectory() const 
{ 
    struct stat s; 
    stat(ep->d_name, &s); 

#if defined(__linux__) 
    if((S_ISDIR(s.st_mode) != 0) != (ep->d_type == DT_DIR)) 
    { 
     throw std::logic_error("Directory is not directory"); 
    } 
#endif 

    return S_ISDIR(s.st_mode); 
} 

bool DirectoryRange::isFile() const 
{ 
    struct stat s; 
    stat(ep->d_name, &s); 

#if defined(__linux__) 
    if((S_ISREG(s.st_mode) != 0) != (ep->d_type == DT_REG)) 
    { 
     throw std::logic_error("File is not file"); 
    } 
#endif 

    return S_ISREG(s.st_mode); 
} 

檢查的dirent值不便攜,但是越來越正確的答案;而統計錯誤,但是便攜。

那麼如果stat看起來不起作用,我該如何檢查目錄?

+0

嘗試Boost.Filesystem的。 –

+0

這裏有一些小瑣碎的瑣事,但並不是所有的文件系統都有文件夾的概念。大型機,特別是沒有。希望你永遠不需要知道這一點,但以防萬一......就是這樣。 – Brad

回答

0

對於初學者來說,S_ISDIRnot a macro that returns a boolean value

計算結果爲非零值如果測試爲真,0,如果 測試爲假。

...

S_ISDIR(m) - 測試目錄。

(強調我的)。顯式轉換爲bool是錯誤的,沒有任何用處。使用這個宏(和其他S_..宏)正確的方法是,簡單地說:

if(S_ISDIR(s.st_mode) == 0) 
{ 
     throw std::logic_error("Directory is not a Directory"); 
} 
+0

我做了更改,但沒有解決它;無論如何,我注意到添加例外之前的錯誤,因爲它試圖打開文件作爲文件夾。 –

0

這似乎是最可靠的:

bool DirectoryRange::isDirectory() const 
{ 
#if defined(__linux__) || (defined(__APPLE__) && defined(__MACH__)) 
    return ep->d_type == DT_DIR; 
#else 
    auto path = syspath(); 
    DIR * dp = opendir(path.c_str()); 
    if(dp) closedir(dp); 
    return dp; 
#endif 
} 

bool DirectoryRange::isFile() const 
{ 
#if defined(__linux__) || (defined(__APPLE__) && defined(__MACH__)) 
    return ep->d_type == DT_REG; 
#else 
    auto path = syspath(); 
    FILE * fp = fopen(path.c_str(), "r"); 
    if(fp) fclose(fp); 
    return fp; 
#endif 
}