사용자 도구

사이트 도구


kb:directorytraversing

Directory Traversing

각종 언어로 디렉토리 순회하는 법

Win32 API

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);
}

MFC

컴파일해보지도 않았다. 그냥 적어놓은 거라서 에러가 있을 수도…

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());
}

*Nix

#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);
}

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")

콜백 구조라 좀 난잡한데, 간단하게 가려면 아래와 같은 방법도 있다.

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

파일 이름의 리스트를 반환하기 때문에 실제 처리는 리스트를 받아서 수행해야 한다.

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")

VB Script

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"
kb/directorytraversing.txt · 마지막으로 수정됨: 2014/11/07 17:46 (바깥 편집)