Page 1 of 3
The problem of running out of hard disk space isn’t nearly as much of a problem as it used to be. Current hard disks have so much space that unless you are doing something that is storage hungry, such as video editing or 3D animation, you probably have lots of spare space. However, solving one problem sometimes creates another. In this case the problem is that a typical disk stores so much information it is difficult to find out what it contains.
If you are simply concerned with finding all the files on a particular topic then you can use a desktop search facility such as Google, Yahoo! or MSN Desktop. A more difficult problem arises when you are confronted with a disk drive and you want to know what sort of use it has been put to. You might have inherited an existing machine with a large hard disk or you might simply not be sure where all your Gbytes are going to.
This project is the construction of a disk analyser which shows you where the big directories lurk and it can be developed and extended to provide a wide range of information concerning the contents of a storage device.
Topics covered include:
- using the TreeView control
- solving problems using recursion
- how to work with files, directories and drives,
- how to use the ProgressBar
- and how to add images to a TreeView
The complete program is in the CodeBin and the final version can be seen in action below:
The first thing a disk analysis program needs is a user interface that allows a device to be selected and, eventually, the results to be presented. The ideal control to use to pick the storage device would be the VB 6 DriveCombo box. Although .NET doesn’t have an equivalent of the DriveCombo box in any form we do have one - see A Drive List Control.
Start a new Windows Application in C# Express or Visual Studio and call it DiskAlyze. Next go to the CodeBin and download and copy DrvCombo to the project folder. Next use the command Project, Add Existing Item and select the file DrvCombo.cs. If you now Build the project you will see a new control added to the toolbox. Simply place an instance of this control on the form and you have provided a way for the user to select the drive to analyse.
The rest of the user interface is just a matter of placing a single button on the form and a TreeView control. The TreeView control can be used for all sorts of tasks and it’s bound to be one of your favourite tools once you get to know it. In this case it is a natural display component because the files stored on the disk form a hierarchy of directories and the TreeView control is essentially a way of displaying and allowing the user to navigate a hierarchy.
The user interface
Climbing a tree
It always helps to attempt something simple before moving on to more complicated tasks. In this case the analysis of the drive will simply provide a picture of how much storage is used by each directory.
What we have to do when the user clicks the Analyze button is to start at the topmost or root directory, find all the files that there are stored in it and work out the total space used.
This would be the end of the story but the root directory also stores other directories and each one of these has files stored in it. So to get a true picture of the total files stored on a disk we also need to perform the same analysis we perform on the root directory on each of the directories it contains.
If you are familiar with programming techniques you may well recognise that this is a recursive algorithm – but don’t panic because recursive methods are much easier in practice than in theory.
The first thing we have to do is get the root directory for the device selected:
private void button1_Click(
object sender, EventArgs e)
string RootDir = drvCombo1.Text;
This gives us our starting point but the easiest way to work with directories is to use a DirectoryInfo object. This allows complete access to the directory and the files and other directories which it might contain. To create a DirectoryInfo object associated with the root we simply use:
The problem is we want to keep track of all the directories that we open as we explore the directory hierarchy. The obvious place to do this is within the TreeView control but there are some minor problems. First we need to look at how the TreeView control works.
The TreeView control can be thought of as a collection of TreeNode objects. Its Nodes property gives you access to its TreeNode collection. Initially a TreeView control doesn’t have any nodes and most of the work in using a TreeView control is adding nodes.
The way in which the TreeNode object works is key to understanding how versatile the TreeView control actually is. Each TreeNode object has its own Nodes collection of TreeNode objects. You can use this TreeNode collection within TreeNode objects to create hierarchies that are as complicated as you like. In most cases there will be a single top-level TreeNode stored in the TreeView control and various levels of child TreeNodes below this.
You might think that as the TreeNode object does everything concerned with creating the hierarchy why bother with the TreeView object?
True enough. If you only want to create a hierarchy and aren’t interested in displaying it then you can just use TreeNode objects. If you are interested in showing the resulting structure to the user, and perhaps even allowing them to interact with it, you need to store the root TreeNode in a TreeView control. This displays all of the TreeNodes it contains as a tree diagram and allows the user to scroll through the structure.
The user can also expand and contract branches of the tree by clicking on plus and minus signs. Each TreeNode’s Text property is displayed on the corresponding node of the tree diagram but it is also possible to display a picture – more of which later.
Being able to organise text and even pictures into a hierarchy isn’t enough for many applications. Programmers often go to great lengths to make the hierarchy of objects that they really want to work with fit into the text or picture categories. In fact this is quite unnecessary. Every TreeNode object has a Tag property which is of type Object and so can be set to reference anything.
In our case we need to keep track of a hierarchy of DirectoryInfo objects and this can be done using the Tag property. Notice that the user doesn’t “see” the Tag property when a collection of TreeNodes are displayed in a TreeView control and so we still have to decide what to store in the Text property.