Click here to Skip to main content
15,897,371 members
Articles / Programming Languages / C#

Directory Size

Rate me:
Please Sign up or sign in to vote.
3.65/5 (13 votes)
9 Apr 2006CPOL2 min read 65.3K   1.2K   32  
An article on getting the size of all folders
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace DirectorySize
{
    public partial class Form1 : Form
    {
        delegate void SetStatusbarCallback(string text);

        private DataTable m_dirs = new DataTable();
        private Dictionary<string, double> m_dirsSize = new Dictionary<string, double>();

        #region Form
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Resize(object sender, EventArgs e)
        {
            if (Form1.ActiveForm != null)
            {
                grdDirectories.Width = (Form1.ActiveForm.Width / 2) - 4;
                grdFiles.Width = (Form1.ActiveForm.Width / 2) - 4;
                grdFiles.Left = (Form1.ActiveForm.Width / 2);
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.Width = Properties.Settings.Default.ProgramWidth;
            this.Height = Properties.Settings.Default.ProgramHeight;

            if (Properties.Settings.Default.ProgramLeft > -100)
            {
                this.Left = Properties.Settings.Default.ProgramLeft;
                this.Top = Properties.Settings.Default.ProgramTop;
            }

            txtFolder.Text = Properties.Settings.Default.Directory;

            grdDirectories.Width = (this.Width / 2) - 4;
            grdFiles.Width = (this.Width / 2) - 4;
            grdFiles.Left = (this.Width / 2);
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            Properties.Settings.Default.ProgramWidth = this.Width;
            Properties.Settings.Default.ProgramHeight = this.Height;
            Properties.Settings.Default.ProgramLeft = this.Left;
            Properties.Settings.Default.ProgramTop = this.Top;

            Properties.Settings.Default.Save();
        }
        #endregion

        #region Scan Directory
        #region Buttons
        private void btnScan_Click(object sender, EventArgs e)
        {
            if (!Directory.Exists(txtFolder.Text))
            {
                MessageBox.Show("The folder does not exist.");
                txtFolder.Focus();
                return;
            }

			Properties.Settings.Default.Directory = txtFolder.Text;
			Properties.Settings.Default.Save();

            btnCancel.Enabled = true;
            btnScan.Enabled = false;
            txtFolder.Enabled = false;
			toolStripProgressBar1.Visible = true;
			toolStripProgressBar1.Value = 0;

			this.Cursor = Cursors.WaitCursor;

            this.backgroundWorker1.RunWorkerAsync();
        }

        private void btnBrowse_Click(object sender, EventArgs e)
        {
            if (txtFolder.Text.Trim() != "")
                folderBrowserDialog1.SelectedPath = txtFolder.Text.Trim();

            if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
                txtFolder.Text = folderBrowserDialog1.SelectedPath;
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.btnCancel.Enabled = false;
            this.backgroundWorker1.CancelAsync();
        }
        #endregion

        /// <summary>
        /// Controls in Windows Forms are bound to a specific thread and are not thread safe. 
        /// Therefore, if you are calling a control's method from a different thread, you must 
        /// use one of the control's invoke methods to marshal the call to the proper thread.
        /// </summary>
        /// <param name="text"></param>
        private void SetStatusBar(string text)
        {
            if (this.statusStrip1.InvokeRequired)
            {
                SetStatusbarCallback d = new SetStatusbarCallback(SetStatusBar);
                this.Invoke(d, new object[] { text });
            }
            else
            {
                this.toolStripStatusLabel1.Text = text;
            }
        }

        /// <summary>
        /// The method that does all the work.
        /// </summary>
        /// <param name="root">The directory to search from.</param>
        /// <returns></returns>
        private bool LoopFolder(DirectoryInfo[] dis)
        {
            if (this.backgroundWorker1.CancellationPending)
                return false;

            foreach (DirectoryInfo di in dis)
            {
				if (this.backgroundWorker1.CancellationPending)
					return false;

                string fullname = di.FullName;

                SetStatusBar(fullname);

                double size = GetFilesSize(di);
                
                DataRow dr = m_dirs.NewRow();

                dr["Name"] = fullname;
                dr["Size"] = size;

                m_dirs.Rows.Add(dr);
                m_dirsSize.Add(fullname, size);

                // sum up the fullsize on all parents
                DirectoryInfo parent = di.Parent;
                while (parent != null && !this.backgroundWorker1.CancellationPending)
                {
                    if (m_dirsSize.ContainsKey(parent.FullName))
                    {
                        m_dirsSize[parent.FullName] += size;
                        parent = parent.Parent;
                    }
                    else
                        break;
                }

				toolStripProgressBar1.PerformStep();
            }

            return true;
        }

        /// <summary>
        /// Gets the total size of all files in the directory.
        /// </summary>
        /// <param name="di"></param>
        /// <returns></returns>
        private double GetFilesSize(DirectoryInfo di)
        {
            double size = 0.0;
            long lSize = 0;
            
            foreach (FileInfo fi in di.GetFiles())
                lSize += fi.Length;

            size = Convert.ToDouble(lSize) / 1024.0 / 1024.0; // size in MB

            return size;
        }

        #region BackgroundWorker
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            // Do not access the form's BackgroundWorker reference directly.
            // Instead, use the reference provided by the sender parameter.
            BackgroundWorker bw = sender as BackgroundWorker;

            // Extract the argument.
            //string[] args = (string[])e.Argument;

            m_dirs = new DataTable();
            m_dirsSize.Clear();

            m_dirs.Columns.Add("Name", typeof(string));
            m_dirs.Columns.Add("Size", typeof(double));
            m_dirs.Columns.Add("Fullsize", typeof(double));

            // Start the time-consuming operation.
            DirectoryInfo di = new DirectoryInfo(txtFolder.Text);
			DirectoryInfo[] dis = di.GetDirectories("*", SearchOption.AllDirectories);

			toolStripProgressBar1.Maximum = dis.Length;

            e.Result = LoopFolder(dis);

            // If the operation was canceled by the user, 
            // set the DoWorkEventArgs.Cancel property to true.
            if (bw.CancellationPending)
            {
                e.Cancel = true;
            }
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            btnCancel.Enabled = false;
            btnScan.Enabled = true;
            txtFolder.Enabled = true;
			toolStripProgressBar1.Visible = false;

            this.Cursor = Cursors.Default;

            if (e.Cancelled)
			{
				// The user canceled the operation.
				MessageBox.Show("Operation was canceled");
			}
            else if (e.Error != null)
            {
                // There was an error during the operation.
                string msg = String.Format("An error occurred: {0}", e.Error.Message);
                MessageBox.Show(msg);
            }
            else
            {
                foreach (DataRow dr in m_dirs.Rows)
                {
                    dr["Size"] = Math.Round((double)dr["Size"], 2);

                    string fullname = (string)dr["Name"];

                    if (m_dirsSize.ContainsKey(fullname))
                        dr["Fullsize"] = Math.Round(m_dirsSize[fullname], 2);
                }

                m_dirs.DefaultView.Sort = "Size desc";
                grdDirectories.DataSource = m_dirs;
                toolStripStatusLabel1.Text = m_dirsSize.Count + " directories found.";
            }
        }
        #endregion
        #endregion

        #region Show files
        private void grdDirectories_SelectionChanged(object sender, EventArgs e)
        {
            if (grdDirectories.SelectedRows.Count == 1)
            {
                string directory = grdDirectories.SelectedRows[0].Cells[0].Value.ToString();

                toolStripStatusLabel1.Text = directory;

                DataTable tblFiles = new DataTable();

                tblFiles.Columns.Add("Name", typeof(string));
                tblFiles.Columns.Add("Size", typeof(double));
                tblFiles.Columns.Add("LastAccessTime", typeof(DateTime));
                tblFiles.Columns.Add("LastWriteTime", typeof(string));
                tblFiles.Columns.Add("CreationTime", typeof(string));
                tblFiles.Columns.Add("ReadOnly", typeof(bool)).ReadOnly = true;
                tblFiles.Columns.Add("Ext", typeof(string));

                DirectoryInfo di = new DirectoryInfo(directory);

                foreach (FileInfo fi in di.GetFiles())
                {
                    DataRow dr = tblFiles.NewRow();

                    dr["Name"] = fi.Name;
                    dr["LastAccessTime"] = fi.LastAccessTime;
                    dr["Size"] = Math.Round(fi.Length / 1024.0 / 1024.0, 2); // size in MB
                    dr["LastWriteTime"] = fi.LastWriteTime;
                    dr["ReadOnly"] = fi.IsReadOnly;
                    dr["CreationTime"] = fi.CreationTime;
                    dr["Ext"] = fi.Extension;

                    tblFiles.Rows.Add(dr);
                }

                tblFiles.DefaultView.Sort = "Size desc";

                grdFiles.DataSource = tblFiles;
            }
        }
        #endregion

	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
Denmark Denmark
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions