dsize.cpp

Download source: dsize.zip


/*  dsize.cpp   $version$   $date$
*
* Microsoft directory search, showing directory size and file count
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <time.h>
#include <io.h>
#include <direct.h>

class FileStats
{
public:
	FileStats(): nFiles(0), size(0), time_write(0), nSubdirs(0) { }
	_int64 nFiles;
	_int64 size;
	_int64 nSubdirs;
	time_t time_write;
	FileStats operator += (const FileStats &s);
	void show();
	void summary();
};



FileStats search(char *name, int depth=0);
void print(const char *fmt, ...);
void format_size(char buf[16], _int64 size);

FILE *out = 0;
int max_depth = 9999;

//-------------------  Main program ----------------------------

int main(int argc, char *argv[])
{
	char *dirname;
	char text[_MAX_PATH];
	char *cp;
	FileStats stats;

	if (argc>1) {
		dirname = argv[1];
		if (argc>2) sscanf(argv[2],"%d",&max_depth);
		printf("maximum depth = %d\n", max_depth);
	}
	else {
		printf("Enter path: ");
		fgets(text,_MAX_PATH,stdin);
		cp = text;
		// elliminate trailing newline
		while (*cp) {
			if (*cp=='\n') *cp = 0;
			else cp++;
		}
		dirname = text;
		if (*dirname==0) return 0;
	}
	//if (argc>2) out = fopen(argv[2],"wt");
	_chdir(dirname);
	_getcwd(text,_MAX_PATH);
	print("\nDirectory %s\n\n",text);
	print("%10s%10s%16s   %s\n","files","subs","bytes","subdir name");
	stats = search(" ");
	stats.summary();
	print("\n");
	return 0;
}

//--------- Global print routine ------------------

void print(const char *fmt, ...)
{
	char text[256];
	va_list marker;
	va_start(marker,fmt);
	vsprintf(text,fmt,marker);
	va_end(marker);
	fputs(text,stdout);
	if (out) fputs(text,out);
}



//---------------- Tree search of directory -------------------


FileStats search(char *dirname, int depth)
{
	int i, done;
	FileStats stats;

	// Search current directory for all files

	_finddata_t info;
	long hFile;

	hFile = _findfirst("*",&info);
	if (hFile == -1L) return stats;
	done = 0;
	
	while (!done) {
		if (info.attrib &  _A_SUBDIR) {
			if (*info.name != '.') stats.nSubdirs++;
		}
		else {
			stats.nFiles++;
			stats.size += info.size;
			if (info.time_write > stats.time_write) stats.time_write = info.time_write;
			//print("%20s %8ld\n",info.name,info.size);
		}
		done = _findnext(hFile,&info);
	}
	_findclose(hFile);
	if (depth<max_depth) {
		stats.show();
		for (i=0; i<depth; i++) print("   ");
		print("%s\n",dirname);
	}

	// search subdirectories

	hFile = _findfirst("*",&info);
	if (hFile == -1L) return stats;


	depth++;
	done = 0;
	while (!done) {
		if (info.attrib & _A_SUBDIR) {
			if (*info.name != '.') {
				_chdir(info.name);
				stats += search(info.name, depth);
				_chdir("..");
			}
		}
		done = _findnext(hFile,&info);
	}
	depth--;
	_findclose(hFile);
	if (depth==max_depth) {
		stats.show();
		for (i=0; i<depth; i++) print("   ");
		print("%s\n",dirname);
	}
	return stats;
}



FileStats FileStats::operator += (const FileStats &s)
{
	nFiles += s.nFiles;
	size += s.size;
	nSubdirs += s.nSubdirs;
	if (s.time_write > time_write) time_write = s.time_write;
	return *this;
}

void FileStats::show()
{
	char buf[32];
	format_size(buf,size);
	print("%10I64d%10I64d%16s",nFiles,nSubdirs,buf);
}

void FileStats::summary()
{
	char buf[32];
	char *cp;
	format_size(buf,size);
	for (cp=buf; *cp==' '; cp++);
	print("\n%I64d file(s) %I64d dir(s) %s bytes\n",nFiles,nSubdirs+1,cp);
	print("\ndate of most recent file: %s\n",ctime(&time_write));
}

void format_size(char *buf, _int64 size)
{
	int i;
	sprintf(buf,"%15I64d",size);
	if (size>999999999L) {
		for (i=0; i<5; i++) buf[i] = buf[i+1];
		buf[5] = ',';
	}
	if (size>999999L) {
		for (i=0; i<8; i++) buf[i] = buf[i+1];
		buf[8] = ',';
	}
	if (size>999L) {
		for (i=0; i<11; i++) buf[i] = buf[i+1];
		buf[11] = ',';
	}
}


Results

You can run a single-level summary by the command
dsize . 1 > dsize.txt
This starts at the current directory and itemizes one-level deep:
maximum depth = 1

Directory C:\classes\ece538\asgn

     files      subs           bytes   subdir name
        11         4         456,422 
        18         1          39,650   2007
         8         0          15,228   2008
         6         0         396,309   asgn2
         5         0          46,310   dsize

48 file(s) 6 dir(s) 953,919 bytes

date of most recent file: Thu May 27 22:23:30 2010

The following screen shot shows the folder from which dsize was executed:


Maintained by John Loomis, updated Thu May 27 22:22:43 2010