리눅스나 유닉스에서 백업프로그램을 짤때 기본이 되는 파일목록을 구하는 함수이다.
아래소스는 하위디렉토포함 파일목록을 구하는 간단한 클래스다.
※VC++, C, C++ 코딩습관이 섞여있어서 미안하다. 그래도 리눅스는 물론이고 유닉스 시스템에서도 무리없이 컴파일 될것이다.
#include <iostream>
#include <cstdio>
#include <stdio.h>
#include <map>
#include <iterator>
#include <string>
#include <fstream>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <strings.h>
#include <memory.h>
using namespace std;
typedef map<string, bool> FILE_LIST;
class CFileList
{
public:
CFileList();
~CFileList();
public:
bool GetFileList(FILE_LIST& list, string strDir); //디렉토리 및 파일목록을 구한다
void ShowFileList(FILE_LIST& list);//리스트를 출력한다
};
CFileList::CFileList()
{
}
CFileList::~CFileList()
{
}
bool CFileList::GetFileList(FILE_LIST& list, string strDir)
{
struct stat statinfo;
memset(&statinfo, 0, sizeof(statinfo));
lstat(strDir.c_str(), &statinfo);
if(!S_ISDIR(statinfo.st_mode))
{
cout<<strDir + " is not directory"<<endl;
return false;
}
DIR *dir;
struct dirent *entry;
if ((dir = opendir(strDir.c_str())) == NULL)
{
cout<<strDir + " open error"<<endl;
return false;
}
while ((entry = readdir(dir)) != NULL)
{
memset(&statinfo, 0, sizeof(statinfo));
string strFilePath = strDir + "/" + entry->d_name;
while(strFilePath.find("//") != string::npos)
strFilePath.replace(strFilePath.find("//"), 2, "/");
lstat(strFilePath.c_str(), &statinfo);
if(S_ISDIR(statinfo.st_mode)) // 디렉토리 이면
{
if(strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue;
list.insert(pair<string, bool>(strFilePath, true)); //디렉토리 경로를 넣음
GetFileList(list, strSubDir); //디렉토리 안으로 들어감
}
else
{
//파일이면
list.insert(pair<string, bool>(strFilePath, false)); //파일경로를 넣음
}
}
//읽은 디렉토리 닫기
closedir(dir);
return true;
}
void CFileList::ShowFileList(FILE_LIST& list)
{
FILE_LIST::iterator itr;
for(itr = list.begin(); itr != list.end(); itr++)
{
if(itr->second == true)
cout<<"[DIRECTORY] " + itr->first<<endl;
else
cout<<"[FILE]" + itr->first<<endl;
}
}
int main(int argc, char* argv[])
{
if(argc != 2)
{
cout<<"usage: filelist [directory path]"<<endl;
return 1;
}
CFileList FileList;
string strSrcDir = argv[1];
FILE_LIST file_list;
FileList.GetFileList(file_list, strSrcDir);
FileList.ShowFileList(file_list);
return 0;
}
#include <cstdio>
#include <stdio.h>
#include <map>
#include <iterator>
#include <string>
#include <fstream>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <strings.h>
#include <memory.h>
using namespace std;
typedef map<string, bool> FILE_LIST;
class CFileList
{
public:
CFileList();
~CFileList();
public:
bool GetFileList(FILE_LIST& list, string strDir); //디렉토리 및 파일목록을 구한다
void ShowFileList(FILE_LIST& list);//리스트를 출력한다
};
CFileList::CFileList()
{
}
CFileList::~CFileList()
{
}
bool CFileList::GetFileList(FILE_LIST& list, string strDir)
{
struct stat statinfo;
memset(&statinfo, 0, sizeof(statinfo));
lstat(strDir.c_str(), &statinfo);
if(!S_ISDIR(statinfo.st_mode))
{
cout<<strDir + " is not directory"<<endl;
return false;
}
DIR *dir;
struct dirent *entry;
if ((dir = opendir(strDir.c_str())) == NULL)
{
cout<<strDir + " open error"<<endl;
return false;
}
while ((entry = readdir(dir)) != NULL)
{
memset(&statinfo, 0, sizeof(statinfo));
string strFilePath = strDir + "/" + entry->d_name;
while(strFilePath.find("//") != string::npos)
strFilePath.replace(strFilePath.find("//"), 2, "/");
lstat(strFilePath.c_str(), &statinfo);
if(S_ISDIR(statinfo.st_mode)) // 디렉토리 이면
{
if(strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue;
list.insert(pair<string, bool>(strFilePath, true)); //디렉토리 경로를 넣음
string strSubDir = strDir + "/" + entry->d_name;
GetFileList(list, strSubDir); //디렉토리 안으로 들어감
}
else
{
//파일이면
list.insert(pair<string, bool>(strFilePath, false)); //파일경로를 넣음
}
}
//읽은 디렉토리 닫기
closedir(dir);
return true;
}
void CFileList::ShowFileList(FILE_LIST& list)
{
FILE_LIST::iterator itr;
for(itr = list.begin(); itr != list.end(); itr++)
{
if(itr->second == true)
cout<<"[DIRECTORY] " + itr->first<<endl;
else
cout<<"[FILE]" + itr->first<<endl;
}
}
int main(int argc, char* argv[])
{
if(argc != 2)
{
cout<<"usage: filelist [directory path]"<<endl;
return 1;
}
CFileList FileList;
string strSrcDir = argv[1];
FILE_LIST file_list;
FileList.GetFileList(file_list, strSrcDir);
FileList.ShowFileList(file_list);
return 0;
}
참고로 이전 날짜를 구하려면 아래처럼 하면 된다. nDays날짜 만큼 전날을 구한다.
string CFileList::GetDiffDay(int nDays)
{
time_t tim=time(NULL) - (24 * 60 * 60 * nDays); //nDays만큼 전날을 구한다
tm *now=localtime(&tim);
char szDiffDay[1024] = {0,};
sprintf(szDiffDay, "%04d%02d%02d", now->tm_year+1900, now->tm_mon+1, now->tm_mday);
return szDiffDay;
}
{
time_t tim=time(NULL) - (24 * 60 * 60 * nDays); //nDays만큼 전날을 구한다
tm *now=localtime(&tim);
char szDiffDay[1024] = {0,};
sprintf(szDiffDay, "%04d%02d%02d", now->tm_year+1900, now->tm_mon+1, now->tm_mday);
return szDiffDay;
}
반응형
'차근차근 > C' 카테고리의 다른 글
fatal error LNK1169: 여러 번 정의된 기호가 있습니다. (2) | 2014.11.19 |
---|---|
비주얼 스튜디오에서의 dirent.h 의 사용 (0) | 2014.10.23 |
HANDLE (0) | 2014.10.22 |
WIN32_FIND_DATA 구조체 (0) | 2014.10.22 |
파일 속성을 검색 및 변경 (0) | 2014.10.22 |