Graphisoft®

InputOutputVersion: 1.0

폴더 트리의 재귀적인 열거



class Folder는 내용(자녀)를 가리키는 책임을 집니다. 여기 내용은 사용자가 제공하는 적절한 Enumeration 콜백 함수를 통해 열거될 수 있는 파일 시스템 엔트리(파일, 폴더, 링크)들을 의미합니다. 그러나 전체 폴더 트리의 재귀적 열거를 자주 필요로 합니다. 이 작업은 TreeEnumerator가 지원합니다. 이것은 사용자가 오버라이드할 수 있는 기본 구현들을 가진 콜백 함수들의 집합을 캡슐화합니다. 새로운 파일, 폴더, 또는 링크를 발견했을 때, 그리고 서브폴더에 들어가거나 나올 때 개별 메소드들이 호출됩니다.
사용자는 TreeEnumerator 인스턴스를 생성해야 합니다. 이때 열거할 루트 폴더를 파라미터로 전달해야 합니다. 열거를 시작하면 적절한 메소드들이 호출될 것입니다. 좀 더 유용한 것들을 수행하려면 폴더 트리를 훑습니다. (이것은 TreeEnumerator의 기본 구현임) 사용자는 TreeEnumerator로부터 파생 class를 만들고 적절한 메소드들을 오버라이드해야 합니다. 모든 "콜백" 메소드의 바디 내부에서 사용자는 현재 파일 시스템 엔트리(파일, 폴더, 링크)의 부모 폴더를 쿼리한다든가, 열거를 중단하는 것과 같은 몇 가지 추가 메소드들을 호출할 수 있습니다.

 

예제

다음 샘플 코드는 주어진 폴더 트리에서 파일들(그리고 파일들을 참고하는 링크들)의 개수를 세는 재귀적인 파일 카운터를 구현합니다. 또한 열거에서 주어진 이름의 폴더(들)를 제외할 수 있습니다. 아래 Test 함수의 바디에서 데스크톱 폴더에 있는 파일들의 개수를 셉니다. 그러나 이름 Temp를 가진 임시 폴더(들)는 건너뜁니다. class RecursiveFileCounterTreeEnumerator에서 파생되었으며 2개의 메소드를 오버라이드합니다: FileFoundFolderFound. 파일 하나를 발견했을 때, 파일 카운터가 증가됩니다. (현존하는 FileFound는 항상 false를 리턴해야 함) 폴더 하나를 발견했을 때, FolderFound 메소드의 리턴 값은 그 폴더의 내용도 열거해야 할지 여부를 결정합니다. true는 열거한다는 것을 의미하므로, 이 샘플에서 현재 폴더의 이름이 임시 폴더의 이름과 같지 않은지 테스트합니다. 이러한 (그 외 몇 가지) 메소드들을 호출하는 순서에 대한 더 많은 정보에 대해서는 class TreeEnumerator를 보십시오.

샘플 코드에서 동작들의 오류 코드들을 처리하지 않지만, 가능성만은 보여준다는 것을 참고하십시오.

이 샘플 작업을 하기 위해, 반드시 InputOutput 모듈을 초기화해야 합니다. (=> 더 많은 정보)



#include "FileSystem.hpp"        // class FileSystem을 사용하는 데 필요한 모든 것을 가져옴 (예. Location)
#include "TreeEnumerator.hpp"    // class TreeEnumerator을 사용하는 데 필요한 모든 것을 가져옴 (예. Folder)
class RecursiveFileCounter: public IO::TreeEnumerator {
private:
    USize     fileCount;    // 폴더 파일 안의 파일들의 개수를 셈
    IO::Name  skip;         // 건너뛸 폴더(들)의 이름

    virtual bool    FileFound   (const IO::Name& /*fileName*/) { fileCount++; return false; }    // 파일을 발견함
    virtual bool    FolderFound (const IO::Name& folderName)   { return (folderName != skip); }  // 폴더를 발견했을 때 건너뛸지 말지 여부

public:
    RecursiveFileCounter (const IO::Folder& root, const IO::Name& folderToSkip):    // 생성자
        IO::TreeEnumerator (root),
        fileCount (0),
        skip (folderToSkip) {}

    USize    GetResult (void) const { return fileCount; }    // 열거의 결과를 리턴 (파일 개수)
};


void    Test (void)
{
    // ...

    IO::Location desktopLoc;    // 데스크톱 폴더의 위치를 저장하게 됨
    GSErrCode errorCode = IO::fileSystem.GetSpecialLocation (IO::FileSystem::Desktop, &desktopLoc);

    IO::Folder desktop (desktopLoc);               // 열거할 폴더 트리의 루트
    RecursiveFileCounter rfc (desktop, "Temp");    // 데스크톱 폴더 상에서 작동하는 파일 카운터 인스턴스, "Temp"는 건너뜀

    if (rfc.Do () == NoError) {                    // 파일 개수 세기 시작
        USize fileCount = rfc.GetResult ();        // 결과의 쿼리
        // ...
    }

    // ...
}