#include #include #include #include #include #include /* Program to walk the directory tree (from a nominated starting point) and report on the size of each file and directory in the first level. The purpose of this is to analyse your disk and work out which directories/files could be deleted to free up space. Author: Nick Gammon Web: http://www.gammon.com.au Date: 8th August 1999 Usage: treeinfo eg. treeinfo c:\games */ void PrintWin32Error (DWORD ErrorCode) { LPVOID lpMsgBuf; FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, ErrorCode, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR) &lpMsgBuf, 0, NULL ); printf("%s", lpMsgBuf ); LocalFree( lpMsgBuf ); } void process_dir (char * dirname, char * subdirname, int level, __int64 * totalsize, long * totalfiles) { char * thisdir = NULL; WIN32_FIND_DATA fileinfo; HANDLE hdl; double mb; // we add 4 below for: // null at end: 1 // \ between dir and subdir name : 1 // \* at end: 2 thisdir = malloc (strlen (dirname) + strlen (subdirname) + 4); if (!thisdir) { printf ("*** Unable to allocate memory for directory name: %s\\%s\n", dirname, subdirname); return; } strcpy (thisdir, dirname); if (strlen (subdirname) > 0) { strcat (thisdir, "\\"); strcat (thisdir, subdirname); } strcat (thisdir, "\\*"); if (strlen (thisdir) > _MAX_PATH) { printf ("*** pathname: \"%s\" is too long to process\n", thisdir); free (thisdir); return; } hdl = FindFirstFile (thisdir, &fileinfo); thisdir [strlen (thisdir) - 2] = 0; // remove wildcard from end if (hdl == INVALID_HANDLE_VALUE) { DWORD nErr = GetLastError (); if (level != 0 && nErr == ERROR_NO_MORE_FILES) { free (thisdir); return; } printf ("*** %s : ", thisdir); PrintWin32Error (nErr); free (thisdir); return; } do { if (fileinfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { if (strcmp (".", fileinfo.cFileName) != 0 && strcmp ("..", fileinfo.cFileName) != 0) { __int64 total = 0; long files = 0; process_dir (thisdir, fileinfo.cFileName, level + 1, &total, &files); *totalsize += total; *totalfiles += files; } } else { LARGE_INTEGER nSize; nSize.HighPart = fileinfo.nFileSizeHigh; nSize.LowPart = fileinfo.nFileSizeLow; *totalsize += nSize.QuadPart; (*totalfiles)++; if (level == 0) { mb = (double) nSize.QuadPart / 1024.0 / 1024.0; printf ("%9.3f Mb %s\\%s \n", mb, thisdir, fileinfo.cFileName); } } if (FindNextFile (hdl, &fileinfo) == 0) { DWORD nErr = GetLastError (); if (nErr != ERROR_NO_MORE_FILES) { printf ("*** %s : ", thisdir); PrintWin32Error (nErr); } FindClose (hdl); if (level == 1) { mb = (double) *totalsize / 1024.0 / 1024.0; printf ("%9.3f Mb %6ld file%s %s \n", mb, *totalfiles, *totalfiles == 1 ? " " : "s", thisdir); } free (thisdir); return; } } while (1); }; int main (int argc, char * argv []) { __int64 total = 0; long files = 0; double mb; char starting_point [_MAX_PATH] = "c:"; if (argc > 1) strcpy (starting_point, argv [1]); // remove trailing backslash from starting point if (starting_point [strlen (starting_point) - 1] == '\\') starting_point [strlen (starting_point) - 1] = 0; printf ("[TREEINFO Version 1.02 Gammon Software Solutions]\n"); if (strcmp (starting_point, "/?") == 0 || strcmp (starting_point, "/help") == 0 || strcmp (starting_point, "/HELP") == 0 ) { printf ("TREEINFO [folder] <-- shows disk usage for \n"); printf ("TREEINFO [folder] | sort /R <-- sorts output\n"); printf ("TREEINFO [folder] | sort /R > myfile.txt <-- sorts, writes to file myfile.txt\n"); printf ("\n"); printf ("Written by Nick Gammon \n"); printf ("Web: http://www.gammon.com.au\n"); printf ("\n"); return 0; } process_dir (starting_point, "", 0, &total, &files); mb = (double) total / 1024.0 / 1024.0; printf ("\n"); printf ("%9.3f Mb %6ld file%s %s (total)\n", mb, files, files == 1 ? " " : "s", starting_point); return 0; }