Я пытаюсь перечислить все файлы в определенном каталоге на общем диске, используя следующий код:
#include <iostream>
#include <string>
#include "dirent.h"
int main ()
{
DIR *directoryHandle = opendir("./temp/");
if (NULL != directoryHandle)
{
dirent *entry = readdir(directoryHandle);
while (NULL != entry)
{
//skip directories and select only files (hopefully)
if ((DT_DIR != entry->d_type) && (DT_REG == entry->d_type || DT_UNKNOWN == entry->d_type))
{
std::cout << "Name: " << entry->d_name << " Type:" << std::to_string(entry->d_type) << std::endl;
}
//go to next entry
entry = readdir(directoryHandle);
}
closedir(directoryHandle);
}
return 0;
}
Проблема в том, что entry-> d_type содержит DT_UNKNOWN для каталогов, а также для файлов в ./temp/
каталог.
Есть ли какой-нибудь (надежный) специфичный для Linux способ попробовать и прочитать каждую запись и определить, является ли это файл или каталог?
Выход из cat /etc/SuSE-release
является:
SUSE Linux Enterprise Desktop 11 (x86_64) ВЕРСИЯ = 11 PATCHLEVEL = 1
Версия для Linux: 2.6.32.59-0.7-default
Тем не менее, я ожидаю, что этот код будет работать и на других платформах.
использование stat
, Вы получите struct stat
с st_mode
поле и макросы S_ISDIR
/S_ISREG
:
isDirectory = S_ISDIR(statBuf.st_mode);
isFile = S_ISREG(statBuf.st_mode);
Увидеть man 2 stat
, Включают sys/stat.h
,
Если вы получаете DT_UNKNOWN
вам придется идти вперед и позвонить lstat()
и осмотреть st_mode
поле, чтобы определить, является ли это файл, каталог или символическая ссылка. Если вас не интересуют символические ссылки, используйте stat()
вместо.
Там есть увеличить библиотеку файловой системы у которого есть команда is_directory.
Использование такой библиотеки, безусловно, сделает код работающим и на других платформах, но я не уверен, что он будет работать для вашей конкретной проблемы.
Дайте это попробовать. Это список файлов в каталоге за вычетом папок:
#include <dirent.h>
#include <stdio.h>
# include <sys/types.h>
# include <sys/mode.h>
# include <stat.h>
DIR *d;
struct dirent *dir;
struct stat s;
d = opendir("./temp/");
if (d)
{
while ((dir = readdir(d)))
{
if (stat(dir->d_name,&s) != 0) {
/* is this a regular file? */
if ((s.st_mode & S_IFMT) == S_IFREG)
printf("%s\n", dir->d_name);
}
}
closedir(d);
}
unsigned char isFolder =0x4;
DIR Dir;
struct dirent *DirEntry;
Dir = opendir("c:/test/")
while(Dir=readdir(Dir))
{
cout << DirEntry->d_name;
if ( DirEntry->d_type == isFolder)
{
cout <<"Found a Directory : " << DirEntry->d_name << endl;
}
}