du for Windows
I often need to get a list of the largest files and directories on my drive. I always used the Unix ‘du’ command to do this — just du -k, sort in reverse and head 50. When I switched to using Windows, I used the ‘du’ found in the Windows binaries of the gnu utilities, then later as those became unavailable, the cygwin utilities.
But cygwin is fat, and I have always wanted a better way. Recently I started using Vista’s “find” feature to get a list of all files above a certain size, then sort. But it’s incredibly slow. My latest look for tools found the sysinternals ‘du’, which has a lot of features, but not what I need.
Finally, I bit the bullet and spent the 10 minutes necessary to write my own. Well, I was rusty and I was half-asleep on an airplane, so it really took 30 minutes. I’m posting the code here for you, so that you can save yourself a whole 30 minutes of effort next time you need to find the largest files on a volume.
Usage: du [drive:|.|*]
I run the command like “du c:\ >sizes.txt” and then open sizes.txt. Finally, back to the comfort of my Unix days, and 10x faster besides. It’s almost the same feeling as when Napster came out and I could find Alan Parsons Project music again.
static void Main(string[] args) { List<KeyValuePair<string, long>> entries = new List<KeyValuePair<string,long>>(); string path; path = args[0]; if (path == “.”) path = Directory.GetCurrentDirectory(); if (path == “*”) { foreach (string drive in Directory.GetLogicalDrives()) { CalculateSize(drive, entries); } } else CalculateSize(path, entries); foreach (KeyValuePair<string,long> kvp in entries) { Console.WriteLine(“{0}t{1}”, kvp.Value, kvp.Key); } } static long CalculateSize(string path, List<KeyValuePair<string, long>> entries) { long cumulativeSize = 0; string[] files; try { files = Directory.GetFiles(path); } catch (Exception ex) { return -1; } foreach (string filename in files) { FileInfo f = new FileInfo(filename); OrderedInsert(filename,f.Length,entries); cumulativeSize += f.Length; } foreach (string dirname in Directory.GetDirectories(path)) { cumulativeSize += CalculateSize(dirname, entries); } OrderedInsert(path, cumulativeSize,entries); return cumulativeSize; } static void OrderedInsert(string path, long size, List<KeyValuePair<string, long>> entries) { KeyValuePair<string, long> entry = new KeyValuePair<string, long>(path, size); int lower = 0; int upper = entries.Count; while (upper > lower + 1) { int middle = lower + (int)Math.Floor((double)(upper - lower) / 2); if (entries[middle].Value < entry.Value) upper = middle; else if (entries[middle].Value > entry.Value) lower = middle; else { entries.Insert(middle, entry); return; } } if (entries.Count == 0) { entries.Insert(0, entry); return; } if (entry.Value > entries[lower].Value) entries.Insert(lower, entry); else entries.Insert(upper, entry); }
October 25th, 2007 at 6:11 pm
I love C#. Too bad it doesn’t work on a mac…
I opened my command prompt and viola.. I already had ‘du’ thanks to GnuWin32. http://gnuwin32.sourceforge.net/
(which is pretty bloated too)
I confess, I’ve never used du before. I installed GnuWin32 at the same time I installed litestep. At the time, I was trying to make my windows experience more like Ubuntu.
October 26th, 2007 at 5:22 pm
Hmm, not bad. packages/coreutils.htm on that site is a minimal package that has all the traditional utilities that I would need to do the same as my program — du, cut, sort, and head.
Many people using Linux today never get a chance to gain proficiency with the old utilities; including grep, sed, etc. But I miss them every day.
Now on windows, we have PowerShell, which blows away anything Unix ever had. But I’ve not forced myself to become proficient, and unfortunately I can’t count on the utils to be everywhere the way the Unix utils were (and even available on my Mac)
March 25th, 2008 at 6:55 am
“Now on windows, we have PowerShell, which blows away anything Unix ever had.”
What?
A.) Do not assert that the tool you admit little familiarity with “blows away” anything.
B.) The PowerShell does not address this problem.
Just not sure where you’re coming from on that one. Du is a basic command that is available on every *nix machine I’ve ever worked on, although there are differences in how it works. The Sysinternals version for Windows is nice, but still a pain when you’re trying to find what’s eating up all your space. I’ve yet to find a good PowerShell script that addresses this issue.
D.
March 30th, 2008 at 6:36 am
David,
I was involved in the earliest design discussions for powershell and followed it’s development closely over a period of years. I have continued to keep up with PowerShell. Stating that I am not “proficient” is not the same as saying that I am not familiar with its capabilities.
I just did a google for “powershell disk free” and found several links. The top link pulls the informations sorted into an excel spreadsheet. I would like to see Unix do that.
March 30th, 2008 at 7:12 am
Here is one: http://www.vistax64.com/powershell/45559-help-creating-powershell-cmndlet-find-all-large-files-folde.html