← 기술 블로그 목록으로 돌아가기
#951 • File System & Disk Governance Architecture

100GB 디스크 용량 잠식과 고아 임시파일 검거: ZeliTree의 50ms 디바운스 DirectoryScanner와 계층형 비율 트리 시각화 아키텍처

"실습용 256GB SSD가 꽉 차서 새 프로젝트가 설치되지 않는데, 윈도우 탐색기는 폴더 용량을 알려주지 않아 막막하셨습니까?" TreeSize 등 상용 유료 도구의 라이선스 단속과 관리자 권한 장벽을 무너뜨리는 Zero-Install 온디바이스 디스크 거버넌스 스위트, DirectoryInfo.EnumerateFileSystemInfos 기반의 파일·폴더 통합 순회, 시스템 보안 폴더에 의한 크래시를 방지하는 IgnoreInaccessible 권한 격리, 수십만 개 파일 순회 중에도 60fps UI를 보장하는 50ms 틱 디바운스(Tick Debounce) 프로그레스 엔진, 그리고 내림차순 용량 정렬과 ProgressBar 점유율 시각화 아키텍처 백서.

"초·중·고 정보 수업에서 언리얼 엔진이나 파이토치 실습을 하려고 하면 '디스크 여유 공간이 부족합니다' 경고창이 뜨며 멈춥니다. 이전 학기 학생들이 남겨둔 수십 기가바이트의 캐시, npm node_modules, 도커(Docker) 이미지, 브라우저 다운로드 잔여물이 범인이지만 윈도우 탐색기는 폴더 크기를 보여주지 않습니다. 유명 디스크 분석 프로그램(TreeSize 등)을 깔자니 관리자 권한(UAC)이 막히고, 무단 설치 시 소프트웨어 단속에 걸립니다. ZeliTree는 단 1바이트의 외부 바이너리 설치 없이, 순수 C# 네이티브로 전체 드라이브의 용량 잠식 주범을 0초 만에 시각화하여 검거합니다."

1. 학교 실습실과 군부대 서버의 '디스크 꽉 참(Disk Full)' 위기: "도대체 어디서 100GB가 사라졌는가?"

수십 명이 공유하는 교육용 PC와 폐쇄망 인트라넷 서버에서는 용량 고갈 문제가 상시 발생합니다:

2. 윈도우 기본 파일 탐색기의 구조적 한계: "폴더 크기 미표시와 일일이 우클릭 속성을 눌러야 하는 비효율"

Windows 파일 탐색기는 파일 크기만 표시할 뿐, 폴더(Directory)의 크기를 열(Column)에 절대 표시하지 않습니다. 모든 하위 트리를 재귀적으로 계산하는 디스크 I/O 비용 때문에 마이크로소프트가 기본 기능을 비활성화해 두었기 때문입니다.

결국 사용자는 의심되는 폴더마다 일일이 우클릭 ➔ [속성]을 눌러 몇 분 동안 계산되는 숫자를 지켜보아야 합니다. 수백 개의 하위 폴더가 존재하는 시스템에서 이 방식은 사실상 문제 해결을 불가능하게 만듭니다.

3. DirectoryScanner의 초고속 순회 엔진: EnumerateFileSystemInfos와 IgnoreInaccessible 권한 격리

ZeliTree는 .NET의 파일 시스템 최적화 API를 극한으로 활용합니다. GetFiles()와 GetDirectories()를 각각 호출하여 2번 디스크를 순회하는 비효율을 없애고, EnumerateFileSystemInfos() 단일 스트림 순회를 통해 폴더와 파일을 동시에 계측합니다.

flowchart TD
    ROOT["루트 경로 선택 (C:\ 등)"] --> SCAN["DirectoryScanner.ScanAsync (Task.Run 격리)"]
    SCAN --> ENUM["dirInfo.EnumerateFileSystemInfos (단일 패스 스트림)"]
    
    ENUM --> CHK{"파일 시스템 엔트리 판별"}
    CHK -- "FileInfo (파일)" --> ADD_FILE["totalSize += fi.Length"]
    CHK -- "DirectoryInfo (하위 폴더)" --> REC["재귀 ScanDirectory 호출"]
    
    REC -- "접근 제한 시스템 폴더" --> IGN["IgnoreInaccessible 옵션 &
UnauthorizedAccessException 예외 격리 (무시 통과)"] REC -- "정상 폴더" --> ADD_DIR["totalSize += child.SizeBytes
item.Children.Add(child)"] ENUM --> TICK{"50ms 경과 체크 (Ticks)"} TICK -- "50ms 초과" --> PROG["ProgressChanged?.Invoke(path) ➔ UI 텍스트 갱신"] TICK -- "50ms 이내" --> SKIP["UI 리포팅 스킵 (프리징 방어)"] ADD_FILE & ADD_DIR --> SORT["item.Children.Sort (용량 내림차순 정렬)"] SORT --> TREE["WinUI 3 TreeView 바인딩 (ProgressBar 점유율 렌더링)"]

또한 일반 계정으로 C:\ 루트를 스캔할 때 System Volume Information이나 Documents and Settings 같은 접근 권한이 없는 시스템 폴더에 진입하더라도, EnumerationOptions { IgnoreInaccessible = true }와 try-catch (UnauthorizedAccessException)를 통해 프로그램 크래시 없이 건너뛰고 스캔을 완벽하게 완주합니다.

C# (DirectoryScanner.cs) 단일 스트림 순회 및 권한 안전 격리
var dirInfo = new DirectoryInfo(path);
var options = new EnumerationOptions { IgnoreInaccessible = true };

// 폴더와 파일을 단일 패스로 동시에 순회 (속도 최적화)
foreach (var fsi in dirInfo.EnumerateFileSystemInfos("*", options))
{
    token.ThrowIfCancellationRequested();

    if (fsi is FileInfo fi)
    {
        totalSize += fi.Length;
    }
    else if (fsi is DirectoryInfo di)
    {
        var child = ScanDirectory(di.FullName, token);
        if (child != null)
        {
            item.Children.Add(child);
            totalSize += child.SizeBytes;
        }
    }
}

4. 50ms 틱 디바운스(Tick Debounce) 프로그레스 리포팅: 수십만 개 파일 스캔 중 UI 프리징 0% 통제

SSD에서 수십만 개의 파일을 초당 수만 개씩 스캔할 때, 파일 하나를 읽을 때마다 UI 스레드로 ProgressChanged 이벤트를 발송하면 어떻게 될까요? WinUI 3의 렌더링 디스패처 큐가 폭주하여 마우스 커서가 멈추고 창이 '응답 없음' 상태에 빠집니다.

⚡ 50ms 틱 디바운스(Tick Debounce) 원리

ZeliTree는 초고속 스캔 스레드에서 DateTime.UtcNow.Ticks를 사용하여 현재 틱과 직전 리포트 틱의 차이를 측정합니다. 경과 시간이 50ms(초당 최대 20회)를 초과했을 때만 단 한 번 이벤트를 호출합니다. 이로써 백그라운드에서는 초당 10만 개의 파일을 최고 속도로 긁어모으면서도, 화면에서는 부드러운 상태 표시와 60fps 반응성을 완벽하게 유지합니다.

C# (DirectoryScanner.cs) 50ms 틱 디바운스 프로그레스 스로틀링
// Progress 리포트 볼륨 조절 (너무 잦은 이벤트 방지, 50ms 마다 1번)
long now = DateTime.UtcNow.Ticks;
if (now - _lastReportTimeTicks > TimeSpan.TicksPerMillisecond * 50)
{
    _lastReportTimeTicks = now;
    ProgressChanged?.Invoke(path);
}

5. 계층형 내림차순 정렬과 ProgressBar 점유 비율(%) 시각화 파이프라인

단순히 트리를 나열하기만 하면 사용자는 수백 개의 폴더 중 어떤 것이 용량을 먹고 있는지 찾아 헤매야 합니다. ZeliTree는 스캔 완료 즉시 하위 항목들을 용량 내림차순(`b.SizeBytes.CompareTo(a.SizeBytes)`)으로 자동 정렬합니다.

가장 용량을 많이 차지하는 '주범' 폴더가 항상 트리 최상단에 노출되며, 부모 폴더 대비 차지하는 용량 비율(Percentage)이 가로 ProgressBar와 텍스트(78.5%)로 직관적으로 렌더링됩니다. 사용자는 트리를 클릭해 들어가며 10초 만에 100GB 임시파일 폴더의 최심부에 도달할 수 있습니다.

6. WinUI 3 TreeView 연동과 드라이브 볼륨 요약 모드 (ShowDriveSummaries)

ZeliTree는 앱을 켜자마자 복잡한 폴더를 강제로 스캔하지 않습니다. ShowDriveSummaries()를 통해 시스템에 장착된 C:, D: 드라이브의 전체 용량, 사용 중인 용량, 여유 공간을 드라이브 요약 카드 형태로 먼저 브리핑합니다.

이후 사용자가 특정 드라이브를 선택하고 [스캔]을 누르면 백그라운드 태스크가 가동되며, 스캔 도중 언제든 중단할 수 있는 CancellationTokenSource 안전 취소 메커니즘을 지원합니다.

7. 기존 디스크 분석기(TreeSize Pro vs WinDirStat vs WizTree vs ZeliTree) 비교 분석

비교 지표 TreeSize Professional WinDirStat WizTree ZeliDesk ZeliTree
라이선스 및 비용 유료 (학교/기관 단속 대상) 무료 오픈소스 상업/기관 유료 라이선스 100% 무료 및 공교육 영구 보급
무설치(Zero-Install) 설치 필수 (관리자 권한) 포터블 가능 포터블 가능 Zero-Install 원클릭 네이티브
스캔 속도 및 렌더링 렉 빠름 극도로 느림 (구형 팩맨 애니메이션) 초고속 (MFT 직독) 50ms 디바운스 초고속 60fps
비관리자 계정 실행 UAC 차단 가능 (권한 오류 팝업 다수) MFT 읽기 위해 관리자 권한 필수 비관리자 완벽 구동 (IgnoreInaccessible)
UI 테마 및 사용성 구형 Win32 UI 20년 전 레거시 인터페이스 Win32 UI 모던 오로라 다크 WinUI 3

8. 결론: "상용 라이선스 단속과 관리자 권한 없는 학교 PC를 위한 가장 완벽한 디스크 거버넌스"

디스크 용량 관리는 단순한 청소 작업이 아니라, 수업과 작전의 연속성을 보장하는 가장 필수적인 시스템 거버넌스입니다. 그러나 관리자 권한이 통제된 학교 PC에서 디스크를 분석하려다 상용 소프트웨어 라이선스 단속에 걸리거나, 구형 도구의 느린 스캔 속도에 좌절하는 일이 반복되어 왔습니다.

ZeliDesk의 ZeliTree는 단 1바이트의 외부 바이너리나 관리자 권한 요구 없이, 50ms 틱 디바운스와 완벽한 권한 예외 격리 위에서 시스템의 모든 용량 잠식 주범을 0초 만에 시각화합니다. 이제 전국의 교육 현장과 공공 전산실은 라이선스 걱정 없이 언제나 쾌적하고 투명한 스토리지 인프라를 유지할 수 있습니다.

← 이전 기술 백서 #952 도메인 스나이핑과 정보 유출 없는 온디바이스 도메인 인텔리전스: ZeliWhois의 RFC 3912 TCP 포트 43 직접 질의와 2단계 리퍼럴 WHOIS 분석 아키텍처 다음 기술 백서 → #950 부팅 10초 단축과 악성 지속성(Persistence) 0초 차단: ZeliStartup의 HKCU·HKLM 4대 시작프로그램 순회와 비파괴적 레지스트리 거버넌스 아키텍처
🌳 ZeliDesk ZeliTree 온디바이스 디스크 분석기 체험하기
사라진 100GB의 원인을 0초 만에 시각화하고, 대용량 임시파일을 완벽히 검거하세요.
72종 유틸리티 전체 둘러보기 →