2017-02-04 20 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 является неправильным, но переносимым.

Так как я могу проверить каталоги портативно, если stat не работает?

+0

Попробуйте Boost.Filesystem. –

+0

Незначительные педантичные мелочи здесь, но не все файловые системы имеют концепцию папок. В частности, мэйнфрейма нет. Надеюсь, вам никогда не понадобится это знать, но на всякий случай ... ну, вот оно. – Brad

ответ

0

Для начала, S_ISDIR является not a macro that returns a boolean value:

Макрос вычисляется в ненулевое значение если тест верно, 0, если тест ложно.

...

S_ISDIR (м) - Тест для каталога.

(акцент мой). Явные приведения к 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 
}