跨平臺編程之Windows模擬Linux opendir / readdir 函數
Windows下模擬Linux opendir, readdir, closedir函數
#include <stdio.h>
#ifdef _MSC_VER
#include <memory>
#include <io.h>
#include <windows.h>
#include <tchar.h>
#include <strsafe.h>
#endif
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <vector>
#include <unistd.h>
#include <dirent.h>
#ifdef _MSC_VER
typedef struct dirent
{
#ifndef __USE_FILE_OFFSET64
__ino_t d_ino;
__off_t d_off;
#else
__ino64_t d_ino;
__off64_t d_off;
#endif
unsigned short int d_reclen;
unsigned char d_type;
char d_name[256]; /* We must not include limits.h! */
} dirent_t;
class dirs_container_t
{
public:
dirs_container_t(int placeholder)
: hFind(INVALID_HANDLE_VALUE)
, readdirInvokedCount(0x00)
{
placeholder++;
}
~dirs_container_t() {
}
public:
DIR * opendir (const char * __name)
{
DWORD dwError=0;
StringCchCopy(szDir, MAX_PATH, __name);
StringCchCat(szDir, MAX_PATH, TEXT("\\*"));
hFind = FindFirstFile(szDir, &ffd);
if (INVALID_HANDLE_VALUE == hFind) {
return (DIR *)INVALID_HANDLE_VALUE;
}
return (DIR *)hFind;
}
struct dirent * readdir (DIR *__dirp)
{
while (__dirp == hFind) {
if (readdirInvokedCount) {
if (FindNextFile(hFind, &ffd) == 0) {
return NULL;
}
}
readdirInvokedCount++;
if (ffd.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)) {
;
} else {
//filesize.LowPart = ffd.nFileSizeLow;
//filesize.HighPart = ffd.nFileSizeHigh;
//_tprintf(TEXT(" %s %ld bytes\n"), ffd.cFileName, filesize.QuadPart);
entry_.d_name[sizeof(entry_.d_name) - 1] = '\0';
entry_.d_type = DT_REG;
strncpy(entry_.d_name, ffd.cFileName, sizeof(entry_.d_name) - 1);
return &entry_;
}
}
return NULL;
}
int closedir (DIR *__dirp)
{
if (__dirp == hFind) {
FindClose(hFind);
}
return 0;
}
private:
struct dirent entry_;
int readdirInvokedCount;
HANDLE hFind;
WIN32_FIND_DATA ffd;
LARGE_INTEGER filesize;
TCHAR szDir[MAX_PATH];
};
class dirs_container_t_loader {
public:
dirs_container_t_loader() {};
~dirs_container_t_loader() {
if (NULL != getInstance()) { delete getInstance(); }
};
static dirs_container_t * getInstance(void) {
static dirs_container_t * g_sema_container_obj = NULL; //(8888);
if (NULL == g_sema_container_obj) { g_sema_container_obj = new dirs_container_t(8888); }
return g_sema_container_obj;
}
};
DIR * opendir (const char * __name)
{
return dirs_container_t_loader::getInstance()->opendir(__name);
}
struct dirent * readdir (DIR *__dirp)
{
return dirs_container_t_loader::getInstance()->readdir(__dirp);
}
int closedir (DIR *__dirp)
{
return dirs_container_t_loader::getInstance()->closedir(__dirp);
}
#endif /* _MSC_VER */