Click here to Skip to main content
Click here to Skip to main content

Disk Usage Viewer

By , 3 Oct 2006
 

DiskUse example screen image

Introduction

This is a disk usage viewer, a tool that helps answer the question, "What is taking up all my disk space?" It displays a tree of folders (directories) starting from the specified folder, listing with each folder the size of all that it contains. Folders are listed in the order of decreasing size. The tree may be expanded to show layers below the topmost.

Background

The inspiration for this tool is the Unix disk usage tool du. The lack of a satisfying, equivalent, commonly-available tool for Windows prompted me to write this one.

Using the code

Using the tool is straightforward:

  1. Click Select, and choose the drive or folder to examine.
  2. Expand any folder in the displayed list to see the details of its contents.
  3. Use the Copy menu to save a text representation of the displayed tree, or to copy the path to the selected folder.

The generated text representation of the tree shown is:

11.9 G  C:
   + 4.16 G  Program Files
   + 2.65 G  Documents and Settings
   + 2.51 G  WINNT
   + 1.08 G  Matt
   + 68.4 M  My Music
   + 28.3 M  dell
   + 19.8 M  Recycled
   + 18.4 M  My Downloads
   + 10.3 M  VXIPNP
   + 1.12 M  samples
   |  + 1.12 M  VC98
   |     + 1.12 M  mfc
   |        + 846 K  ole
   |        |  + 846 K  wordpad
   |        |     + 27 K  res
   |        |     + 0 K  UniDebug
   |        + 275 K  general
   |           + 275 K  LISTHDR
   |              + 33 K  res
   |              + 0 K  Release
   + 1 K  cygwin
   + 0 K  WUTemp

The code recursively explores the folder structure below the selected root folder, and populates a Windows tree control accordingly. The application is a single document (SDI) MFC app generated by AppWizard, with a CTreeView used for the view class.

Most of the functionality is implemented in the CDiskUseView class, which has close access to its underlying tree control. Event handlers for the menu operations appear in the CMainFrame class.

Points of interest

A tree, such as a drive's folder structure, is inherently a recursive structure, so working with a tree is a natural application for recursive programming techniques. The function ScanDirectory sums the sizes of the files in a directory, and calls itself recursively to find the sizes of directories it contains. The function DisplaySubtree writes a text representation of one folder in the tree, and calls itself recursively for the levels below. And the function ExpandTreeLevel calls itself recursively to adjust the tree control view so that one, two, or all levels are visible.

For a problem such as this one, using recursion realizes the desired functionality with a very small amount of code. The recursive approach may initially seem confounding and confusing, but it's not difficult. This small program can serve as an example of how it is done.

Acknowledgment

Thanks to S. Sokolenko, whose GetFolder wrapper for SHBrowseForFolder saved me the effort of learning the details of that operation.

History

  • Oct. 3, 2006: Update to handle directory names that include a dot.
  • Sept. 26, 2006: Created.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Matt Fichtenbaum
Web Developer
United States United States
Electrical engineer turned software engineer, working in automated test equipment development. Enjoy partitioning hardware/software systems into logical, coherent structures. Incorrigible builder of tools.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMultithreadedmembercjbarth16-Mar-09 13:59 
GeneralRe: MultithreadedmemberMatt Fichtenbaum16-Mar-09 14:56 
General"rlivelyppk" missed the pointmemberjerryshirley12-Oct-06 19:55 
GeneralSupport for Commandline Arguments ... [modified]memberMartin081511-Oct-06 23:46 
Hello,
 
I just patched the sources to allow diskuse.exe to accept a directory to scan.
 
The Changes:
1. DiskUse.cpp:
a) added between ParseCommandLine and ProcessShellCommand:
	// get the directory from the commandline
	//
	CString selectedDir = "";
 
	selectedDir	= cmdInfo.m_strFileName;
 
	// reset the cmdInfo object to "show" an empty commandline
	//
	cmdInfo.m_nShellCommand = CCommandLineInfo::FileNew;
	cmdInfo.m_strFileName   = "";
 
b) added after ProcessShellCommand:
	// strip any enclosing quotes
	//
	selectedDir.Trim('\"');
 
	// start scanning
	//
	((CMainFrame *) m_pMainWnd)->OnSelectedDir(selectedDir);
 
2. MainFrm.h:
a) Method Declaration added in the public class declaration section for the implementation:
	void OnSelectedDir(CString selectedDir = "");
 
3. MainFrm.cpp:
a) Method OnMnuSelect replaced:
	void CMainFrame::OnMnuSelect() 
	{
		CString csDir;
 
		// get the root folder for our search
		if (GetFolder(&csDir, "Select the topmost directory to analyze", m_hWnd, NULL, LPCTSTR(m_csCurrentDir)))
		{
			OnSelectedDir(csDir);
		}
	}
 
	void CMainFrame::OnSelectedDir(CString selectedDir)
	{
		if (selectedDir.GetLength() > 0)
			m_csCurrentDir = selectedDir;
 
		int nLength = m_csCurrentDir.GetLength();
 
		if (nLength > 0) {
			SetWindowText("DiskUse - Working ...");
			UpdateWindow();
			CWaitCursor wc;
 
			if (m_csCurrentDir.GetAt(nLength - 1) == '\\')
				m_csCurrentDir.TrimRight('\\');
 
			CDiskUseView *pView = (CDiskUseView *) GetActiveView();
 
			// all the works are in the view class, which owns the underlying tree control
			unsigned __int64 nSize = pView->DoScan(LPCTSTR(m_csCurrentDir));
 
			// finished - display the root folder and its size in the title bar
			char buff[256];
			sprintf(buff, "%s - ", LPCTSTR(m_csCurrentDir));
			FormatSizeVal(buff + strlen(buff), (nSize + 1023) / 1024);
			strcat(buff, "bytes");
			SetWindowText(buff);
			m_bHasContent = (nSize > 0);
		}
	}
 
It works and its good for me, working often with the commandline or the "Run" dialog from the start menu. And additionally now it is possible to add an Explorer Context menu entry for the file type "Folder", so that the "Disk Usage Viewer" could be used from inside the Explorer, after right-clicking on a folder or drive.
 
Best regards,
 
Martin
 
P.S.: I added a "&Refresh" menu entry (ID_MNU_REFRESH) and a accelerator (ID_REFRESH_TREE). Both have the simple event handlers:
 
	void CMainFrame::OnRefreshTree()
	{
		OnSelectedDir();
	}
 
	void CMainFrame::OnMnuRefresh()
	{
		OnSelectedDir();
	}
 

 

-- modified at 7:45 Thursday 12th October, 2006
GeneralNot all directories scannedmember~MyXa~10-Oct-06 1:02 
GeneralRe: Not all directories scannedmemberMatt Fichtenbaum11-Oct-06 2:02 
GeneralSequoiaViewmember~MyXa~10-Oct-06 0:45 
GeneralRe: SequoiaViewmemberjauming25-Apr-09 4:46 
Generali.Disk performs this functionmemberrlivelyppk4-Oct-06 9:05 
GeneralRe: i.Disk performs this functionmemberAnonymuos4-Oct-06 9:43 
GeneralRe: i.Disk performs this function [modified]memberrlivelyppk4-Oct-06 9:52 
GeneralA few suggestionsmemberPhil Atkin2-Oct-06 22:39 
GeneralNeat little projectmemberUdnaan2-Oct-06 21:45 
GeneralRe: Neat little projectmemberMatt Fichtenbaum3-Oct-06 5:56 
GeneralGreat timing!memberCaveManJ2-Oct-06 17:53 
GeneralMost useful - but truncates some directory namesmemberRogerLainson2-Oct-06 17:19 
GeneralRe: Most useful - but truncates some directory namesmemberMatt Fichtenbaum3-Oct-06 4:50 
GeneralIt's a very useful app for mememberraulcigil227-Sep-06 22:08 
GeneralGreat!memberAnonymuos26-Sep-06 11:44 
GeneralRe: Great!memberMatt Fichtenbaum29-Sep-06 1:58 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130617.1 | Last Updated 3 Oct 2006
Article Copyright 2006 by Matt Fichtenbaum
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid