사용자 도구

사이트 도구


kb:directorytraversing

차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.

차이 보기로 링크

kb:directorytraversing [2014/11/07 17:46] (현재)
줄 1: 줄 1:
 +====== Directory Traversing ======
 +각종 언어로 디렉토리 순회하는 법
 +
 +====== Win32 API ======
 +<code cpp>
 +static const int INVALID_PTR = -1;
 +
 +void traverse(const string& root)
 +{
 +    string search = root;
 +
 +    if (search.empty()) search += "​.\\";​
 +    else if (search[search.size()-1] != '​\\'​) search += "​\\";​
 +    ​
 +    search += "​*.*";​
 +
 +    __finddata64_t fd;
 +
 +    intptr_t ptr = _findfirst64(search.c_str(),​ &fd);
 +    if (ptr == INVALID_PTR) return;
 +    ​
 +    do
 +    {
 +        string filename = fd.name;
 +    ​
 +        if (fd.attrib & _A_SUBDIR)
 +        {
 +            cout << "Dir : " << filename << endl;
 +            ​
 +            if (filename != "​."​ && filename != "​.."​)
 +                traverse(search.substr(0,​ search.size()-3) + filename);
 +        }
 +        else
 +        {
 +            cout << "File : " << filename << endl;
 +        }
 +    }
 +    while (_findnext64(ptr,​ &fd) == 0);
 +    ​
 +    findclose(ptr);​
 +}
 +</​code>​
 +
 +====== MFC ======
 +컴파일해보지도 않았다. 그냥 적어놓은 거라서 에러가 있을 수도...
 +<code cpp>
 +void traverse(const string& root)
 +{
 +    string search = root;
 +
 +    if (search.empty()) search += "​.\\";​
 +    else if (search[search.size()-1] != '​\\'​) search += "​\\";​
 +    ​
 +    search += "​*.*";​
 +
 +    CFileFind ff;
 +    ​
 +    if (!ff.FindFile(search.c_str())) ​
 +        return;
 +        ​
 +    do
 +    {
 +        if (ff.isDirectory())
 +        {
 +            cout << "​Dir:"​ << ff.GetFileName() << endl;
 +            ​
 +            if (!ff.isDots())
 +            {
 +                traverse(search.substr(0,​ search.size()-3) + ff.GetFileName());​
 +            }
 +        }
 +        else
 +        {
 +            cout << "​File:"​ << ff.GetFileName() << endl;
 +        }
 +    }
 +    while (ff.FindNextFile());​
 +}
 +</​code>​
 +
 +====== *Nix ======
 +<code cpp>
 +#include <​sys/​types.h>​
 +#include <​sys/​stat.h>​
 +#include <​dirent.h>​
 +
 +void traverse(const string& root)
 +{
 +    DIR* dir = opendir(root.c_str());​
 +    if (dir == NULL) return;
 +
 +    struct dirent* ent;
 +    while ((ent = readdir(dir)) != NULL)
 +    {
 +        string filename = ent->​d_name;​
 +
 +        if (filename == "​."​ || filename == "​.."​)
 +            continue;
 +
 +        string fullname = root + "/"​ + filename;
 +
 +        struct stat s;
 +        stat(fullname.c_str(),​ &s);
 +
 +        if (S_ISDIR(s.st_mode))
 +        {
 +            cout << "Dir : " << fullname << endl;
 +            traverse(fullname);​
 +        }
 +        else if (S_ISREG(s.st_mode))
 +        {
 +            cout << "File : " << fullname << endl;
 +        }
 +    }
 +
 +    closedir(dir);​
 +}
 +</​code>​
 +
 +====== Python ======
 +<code python>
 +import os
 +
 +def callback(arg,​ directory, files):
 +    for file in files:
 +        full_name = os.path.join(directory,​ file)
 +        if os.path.isfile(full_name):​
 +            print "File : ", full_name, repr(arg)
 +        elif os.path.isdir(full_name):​
 +            print "Dir : ", full_name, repr(arg)
 +
 +os.path.walk("​C:​\\Somewhere",​ callback, "user data")
 +</​code>​
 +        ​
 +콜백 구조라 좀 난잡한데,​ 간단하게 가려면 아래와 같은 방법도 있다.
 +
 +<code python>
 +import os
 +
 +def traverse(path):​
 +    if path[-1] != os.sep:
 +        path += os.sep
 +
 +    fileList = []
 +
 +    for name in os.listdir(path):​
 +        full_name = path + name
 +        if os.path.isdir(full_name):​
 +            fileList += traverse(full_name)
 +        else:
 +            fileList.append(full_name)
 +
 +    return fileList
 +</​code>​ 파일 이름의 리스트를 반환하기 때문에 실제 처리는 리스트를 받아서 수행해야 한다.
 +
 +====== Ruby ======
 +<code ruby>
 +def traverse(path)
 +    Dir.foreach(path) { |name|
 +        next if name == '​.'​ or name == '​..'​
 +        full_name = File.join(path,​ name)
 +        case File.ftype(full_name)
 +            when "​file"​
 +                print("​File : #​{full_name}\n"​)
 +            when "​directory"​
 +                print("​Dir : #​{full_name}\n"​)
 +                traverse(full_name)
 +        end
 +    }
 +end
 +
 +traverse("​C:​\\Somewhere"​)
 +</​code>​
 +
 +====== VB Script ======
 +<code vb>
 +Set Fso = CreateObject("​Scripting.FileSystemObject"​) ​
 +
 +Sub Traverse(path) ​
 +    Set folder = Fso.GetFolder(path) ​
 +    Set files = folder.Files ​
 +    Set subfolders = folder.SubFolders ​
 + 
 +    For Each file In files 
 +        WScript.Echo "File : " & file
 +    Next 
 +     
 +    For Each subfolder In subfolders ​
 +        WScript.Echo "Dir : " & subfolder
 +        Traverse subfolder.Path
 +    Next 
 +End Sub
 +
 +Traverse "​C:​\Somewhere"​
 +</​code>​
 +
  
kb/directorytraversing.txt · 마지막으로 수정됨: 2014/11/07 17:46 (바깥 편집)