식별하기(Identify) vs. 일치하기(Match)
비록 FileTypeManager 클래스의 식별 함수(Identify, IdentifyOwn)들이 중요한 용도를 갖고 있기는 하지만 오용될 수 있습니다. 이 함수들은 가장 강력한 식별 함수들입니다. 그것들의 목표는 "매직 번호"를 읽기 위해 파일을 여는 (매우 자주) 콜백 함수를 포함하는 파일 타입을 지원하는 모든 정보를 사용하여 일치 레벨을 기반으로 가장 잘 일치하는 FileType을 찾는 것입니다. 이것은 시간과 프로세싱 파워를 많이 요구하는 작업이 될 수 있습니다. 이 함수들은 단지 어떤 파일이 특정한 경우에 대하여 좋거나 그렇지 않다는 것을 결정하는 것이 목표인 상황에서 사용해서는 안 됩니다. 다음 예제는 나쁜 사용 예시를 보여줍니다.
FTM::GeneralID actFType = FTM::FileTypeManager::Identify (IO::Location(spec)); if ( actFType == ModulFile || actFType == PlanFile || actFType == A_PlanFile || actFType == Bak_PlanFile || actFType == WGProjFile || actFType == WGClientFile || actFType == A_WGProjFile || actFType == A_WGClientFile || actFType == Bak_WGProjFile || actFType == Bak_WGClientFile) { // 무언가를 수행함 } else if ( actFType == PictFile || actFType == TIFFFile || actFType == GIFFile || actFType == JPEGFile || actFType == BMPFile) { // 무언가를 수행함 }
이 경우 우리는 관심이 없는 모든 타입들을 식별하는 데 시간을 허비하게 됩니다. 예를 들어, 만약 일부 중첩하는 확장자와 mac type을 이용하는 타입 데이터베이스가 여러 타입으로 가득 차 있다고 하면 매번 이 코드가 실행되고 if 분기 중에서 true가 하나도 없을 때, Identify 함수는 관심 없는 타입들의 콜백 함수들을 실행할 것이며 필요한 것보다 훨씬 더 많은 정보를 추출할 것입니다.
다음 코드 예제는 좀 더 나은 접근 방식을 보여줍니다.
IO::Location loc = IO::Location(spec); if ( FTM::FileTypeManager::Match (loc, ModulFile) || FTM::FileTypeManager::Match (loc, PlanFile) || FTM::FileTypeManager::Match (loc, A_PlanFile) || FTM::FileTypeManager::Match (loc, Bak_PlanFile) || FTM::FileTypeManager::Match (loc, WGProjFile) || FTM::FileTypeManager::Match (loc, WGClientFile) || FTM::FileTypeManager::Match (loc, A_WGProjFile) || FTM::FileTypeManager::Match (loc, A_WGClientFile) || FTM::FileTypeManager::Match (loc, Bak_WGProjFile) || FTM::FileTypeManager::Match (loc, Bak_WGClientFile)) { // 무언가를 수행함 } else if ( FTM::FileTypeManager::Match (loc, PictFile) || FTM::FileTypeManager::Match (loc, TIFFFile) || FTM::FileTypeManager::Match (loc, GIFFile) || FTM::FileTypeManager::Match (loc, JPEGFile) || FTM::FileTypeManager::Match (loc, BMPFile)) { // 무언가를 수행함 }
이 경우, 표현식에 포함된 타입들만 테스트합니다. if 분기 내부에 있는 결정은 여전히 불필요하며 추가 처리를 요구합니다. 만약 1번째 if 분기 안에 있는 타입들이 동일한 확장자를 사용한다고 가정하면, 우리는 무엇이 가장 잘 일치하는지 결정하려고 여전히 노력해야 하고 이 정보를 사용하지 않습니다. 더 좋은 방법은 공통적으로 테스트할 타입들의 그룹을 만들고 이 그룹에 대하여 일치시키는 것입니다. 이 경우 Match 함수는 동일하거나 더 나은 일치 레벨에 대한 후보들이 있는 그룹 외부에 다른 타입들이 있는 경우에만 가장 나은 일치를 찾으려고 하지 않을 것입니다. 신중한 그룹화를 통해 콜백 함수들의 불필요한 호출을 피할 수 있습니다.
{ // 생성 a local manager FTM::FileTypeManager modulFTManager ("tempid"); // 관리자에게 그룹들을 추가함 FTM::GroupID planTypes = modulFTManager.AddGroup ("Plan Types"); FTM::GroupID imageTypes = modulFTManager.AddGroup ("Image Types"); // 그룹들 안에 타입들 삽입 modulFTManager.AddTypeToGroup (ModulFile, planTypes); modulFTManager.AddTypeToGroup (PlanFile, planTypes); modulFTManager.AddTypeToGroup (A_PlanFile, planTypes); modulFTManager.AddTypeToGroup (Bak_PlanFile, planTypes); modulFTManager.AddTypeToGroup (WGProjFile, planTypes); modulFTManager.AddTypeToGroup (WGClientFile, planTypes); modulFTManager.AddTypeToGroup (A_WGProjFile, planTypes); modulFTManager.AddTypeToGroup (A_WGClientFile, planTypes); modulFTManager.AddTypeToGroup (Bak_WGProjFile, planTypes); modulFTManager.AddTypeToGroup (Bak_WGClientFile planTypes); modulFTManager.AddTypeToGroup (PictFile, imageTypes); modulFTManager.AddTypeToGroup (TIFFFile, imageTypes); modulFTManager.AddTypeToGroup (GIFFile, imageTypes); modulFTManager.AddTypeToGroup (JPEGFile, imageTypes); modulFTManager.AddTypeToGroup (BMPFile imageTypes); IO::Location loc = IO::Location(spec); // 그룹들을 대상으로 테스트함 if (FTM::FileTypeManager::Match (loc, planTypes)) { // 무언가를 수행함 } else if (FTM::FileTypeManager::Match (loc, imageTypes)) { // 다른 무언가를 수행함 } // 로컬 관리자의 소멸시에 이 관리자를 통해 추가된 모든 항목들이 정리됨 // (관리자에는 타입들, 그룹들, 그리고 서로 간의 연결들이 포함되어 있음) }만약 Match에 대하여 함께 그룹화되었다면, 이런 식으로 FileTypeManager는 동일한 확장자를 사용하여 타입들 간에 결정하려고 시도하지 않을 것입니다. 만약 동일한 확장자를 가진 그룹 외부에 다른 타입들이 없다면, 이 동작은 매우 효과적으로 작동할 것입니다.