VB icon

Backup Folder Version 3.2 20/9/2016

Email
Submitted on: 9/20/2016 9:13:33 PM
By: Ben  
Level: Beginner
User Rating: Unrated
Compatibility: C++ (general), Microsoft Visual C++
Views: 607
 
     This is the new version of my ever developing file copying tool. This version builds off version 2 and also from my DirTree project. this now has 11 flags you can use, it now supports copying files from all sub folders. Some bugs have been fixed an some new flags have been added, see the screen shot for more help. Been tested in Visual C++ 2010 and Visual C++ 2013 Comments questions welcome I like to know what you all think. ps thanks for any feed back I recived from others.

 
code:
Can't Copy and Paste this?
Click here for a copy-and-paste friendly version of this code!
				
//**************************************
// Name: Backup Folder Version 3.2 20/9/2016
// Description:This is the new version of my ever developing file copying tool. This version builds off version 2 and also from my DirTree project. this now has 11 flags you can use, it now supports copying files from all sub folders. Some bugs have been fixed an some new flags have been added, see the screen shot for more help. Been tested in Visual C++ 2010 and Visual C++ 2013 Comments questions welcome I like to know what you all think. ps thanks for any feed back I recived from others.
// By: Ben
//**************************************

/*
 Expert Backup Folders 22:10 20/09/2016
 Version 3.2
 By Ben a.k.a DreamVB
*/
#include <iostream>
#include <Windows.h>
#include <string>
#include <algorithm>
#include <conio.h>
using namespace std;
using std::cout;
using std::endl;
//Define program version
#define version 3.2
enum TAction
{
	F_COPY = 0,
	F_MOVE = 1
};
int Copyed = 0;
int Skipped = 0;
//
bool OverReadOnly = false;
bool bCopyFiles = true;
bool NoMsg = false;
bool ShowFullName = false;
bool ShowStatusInfo = false;
bool ShowStartMsg = false;
bool SetAchiveOnlyAttr = false;
bool IncludeFullRelativePath = false;
bool ZeroLenFiles = false;
TAction m_Action;
string sStatusA = "";
string sStatusB = "";
bool CreateZeroLengthFile(string src){
	bool IsGood = true;
	FILE *fp = NULL;
	//Just creats an empry file.
	fp = fopen(src.c_str(), "w");
	if (!fp){
		IsGood = false;
	}
	//Close file.
	fclose(fp);
	return IsGood;
}
string TrimR(string src){
	// trim trailing spaces
	size_t endpos = src.find_last_not_of(" \t");
	if (string::npos != endpos)
	{
		src = src.substr(0, endpos + 1);
	}
	return src;
}
string TrimL(string src){
	// trim leading spaces
	size_t startpos = src.find_first_not_of(" \t");
	if (string::npos != startpos)
	{
		src = src.substr(startpos);
	}
	return src;
}
string TrimAll(string src){
	return TrimL(TrimR(src));
}
string LCase(string src)
{
	string Temp = src;
	std::transform(Temp.begin(), Temp.end(), Temp.begin(), ::tolower);
	return Temp;
}
string FixPath(string src){
	if (src[src.length() - 1] != '\\'){
		return src + "\\";
	}
	return src;
}
bool FileExists(string filename){
	//Check if a file was found.
	if (GetFileAttributesA(filename.c_str()) == INVALID_FILE_ATTRIBUTES){
		return false;
	}
	return true;
}
bool DirExists(string filename){
	if ((GetFileAttributesA(filename.c_str()) != FILE_ATTRIBUTE_DIRECTORY)){
		return false;
	}
	return true;
}
bool MyFileCopy(string src, string dest, int chunksize = 2048){
	FILE *fin = NULL;
	FILE *fout = NULL;
	char *Buffer = NULL;
	size_t BytesRead = 0;
	size_t BytesWrite = 0;
	//Open source file.
	fin = fopen(src.c_str(), "rb");
	if (!fin){
		return false;
	}
	fout = fopen(dest.c_str(), "wb");
	if (!fout){
		fclose(fin);
		return false;
	}
	//Resize Buffer
	Buffer = new char[chunksize];
	//Do file copy.
	//Get first data
	BytesRead = fread(Buffer, sizeof(char), chunksize, fin);
	//While not end of file read
	while (!feof(fin)){
		//Write data
		BytesWrite = fwrite(Buffer, sizeof(char), BytesRead, fout);
		//Read in new data.
		BytesRead = fread(Buffer, sizeof(char), chunksize, fin);
	}
	//Write remaining data.
	BytesWrite = fwrite(Buffer, sizeof(char), BytesRead, fout);
	//Tidy up time.
	fclose(fout);
	fclose(fin);
	delete[]Buffer;
	return true;
}
void MyCreateDir(string PathName){
	int i = 0;
	int j = 0;
	string sPart = "";
	string sDir = "";
	//Append end backslash.
	if (!PathName[PathName.length() - 1] != '\\'){
		PathName += "\\";
	}
	//
	while (i < PathName.length()){
		if (PathName[i] == '\\'){
			//The path to create
			sDir += sPart + "\\";
			//Check for folder.
			if ((GetFileAttributesA(sDir.c_str()) & FILE_ATTRIBUTE_DIRECTORY)){
				//Create folder
				CreateDirectoryA(sDir.c_str(), NULL);
			}
			//Clear parts.
			sPart.clear();
		}
		else{
			//Split the string by backslash
			sPart += PathName[i];
		}
		//INC counter
		i++;
	}
	sPart.clear();
	sDir.clear();
}
bool BackupAction(TAction action, string srcfile, string destfile, bool bFail){
	bool IsGood = false;
	//Copy file with out moveing it
	if (action == F_COPY){
		//IsGood = CopyFileA(srcfile.c_str(), destfile.c_str(), bFail);
		if (ZeroLenFiles){
			//Create zero size file.
			IsGood = CreateZeroLengthFile(destfile.c_str());
		}
		else{
			//Buffered file copy.
			IsGood = MyFileCopy(srcfile.c_str(), destfile.c_str(), 2048);
		}
	}
	//Copys a file and delets from the source folder.
	if (action == F_MOVE){
		IsGood = MoveFileA(srcfile.c_str(), destfile.c_str());
	}
	return IsGood;
}
void DirTree(string Path, string lzDestPath, string FileType, bool AllDirs){
	HANDLE f = 0;
	WIN32_FIND_DATAA wfd;
	int pos = string::npos;
	string lzPath = "";
	string lzCopyTo = "";
	string NewPath = "";
	string lzSrcFile = "";
	string lzDestFile = "";
	string Temp = "";
	string fExt = "";
	//Append backslash to path.
	lzPath = FixPath(Path);
	//Find first file.
	f = FindFirstFileA((lzPath + "*.*").c_str(), &wfd);
	//Check for inaild path.
	if (f == INVALID_HANDLE_VALUE){
		cout << "Folder or files not found." << endl << lzPath.c_str() << endl;
		FindClose(f);
		exit(1);
	}
	//Gets the list of files
	do{
		if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY){
			//Skip dots eg . and ..
			if ((stricmp(wfd.cFileName, ".") == 0) | (stricmp(wfd.cFileName, "..") == 0)){
				continue;
			}
			//Fix and build path.
			NewPath = FixPath(lzPath + wfd.cFileName);
			//Scan all sub folders.
			if (AllDirs){
				//Check if the folder is found/
				if (DirExists(NewPath)){
					//Recall DirTree get the next files
					DirTree(NewPath, lzDestPath, FileType, AllDirs);
				}
			}
		}
		else{
			if (FileType.length() != 0){
				fExt = LCase(wfd.cFileName);
				pos = fExt.find_last_of('.');
				if (pos != string::npos){
					fExt.erase(0, pos);
					if (fExt == FileType){
						//Set src filename
						lzSrcFile = lzPath + wfd.cFileName;
					}
				}
			}
			else{
				//Set src filename
				lzSrcFile = lzPath + wfd.cFileName;
			}
			//Test if we have a filename.
			if (lzSrcFile.length() != 0){
				//Set dest filename
				Temp = lzSrcFile;
				pos = Temp.find_first_of('\\');
				if (pos != string::npos){
					Temp.erase(0, pos + 1);
				}
				//Used for Relative paths
				if (!IncludeFullRelativePath){
					pos = Temp.find_first_of('\\');
					if (pos != string::npos){
						Temp.erase(0, pos);
					}
				}
				//Set dest filename
				lzDestFile = lzDestPath + Temp;
				//Extract the dest full path.
				pos = lzDestFile.find_last_of('\\');
				if (pos != string::npos){
					lzCopyTo = lzDestFile.substr(0, pos);
				}
				//Create destination folders
				if (!DirExists(lzCopyTo)){
					MyCreateDir(lzCopyTo);
				}
				//Check if copying files
				if (bCopyFiles){
					//Check if writeing over old file.
					if (OverReadOnly){
						if (FileExists(lzDestFile)){
							//Remove all file attrib and set to normal
							SetFileAttributesA(lzDestFile.c_str(), FILE_ATTRIBUTE_NORMAL);
						}
					}
					//Copy the src file over to the folder.
					if (!BackupAction(m_Action, lzSrcFile.c_str(), lzDestFile.c_str(), false)) {
						if (!NoMsg){
							if (ShowFullName){
								cout << lzDestFile.c_str() << sStatusB << endl;
							}
							else{
								cout << wfd.cFileName << sStatusB << endl;
							}
							Skipped++;
						}
					}
					else{
						if (!NoMsg){
							if (ShowFullName){
								cout << lzDestFile.c_str() << sStatusA << endl;
							}
							else{
								cout << wfd.cFileName << sStatusA << endl;
							}
							Copyed++;
						}
						//Set file attrib to achive
						if (SetAchiveOnlyAttr){
							SetFileAttributesA(lzDestFile.c_str(), FILE_ATTRIBUTE_ARCHIVE);
						}
					}
					lzSrcFile.clear();
					Temp.clear();
				}
			}
		}
	} while (FindNextFileA(f, &wfd) != 0);
	//Close file
	FindClose(f);
}
int main(int argc, char *argv[]){
	string Temp = "";
	string DeskFolder = "";
	string fExt = "";
	string Flags = "";
	bool ScanAllDirs = false;
	int pos = string::npos;
	int i = 3;
	m_Action = F_COPY;
	//Check for help switch
	if (argc == 2){
		Flags = argv[1];
		//If help switch display online help
		if (Flags == "/?"){
			cout << "-------------------------------------------------------------------------------" << endl;
			cout << " Backup Folders version " << version << " :: Expert Backup Copy For Windows" << endl;
			cout << "-------------------------------------------------------------------------------" << endl;
			cout << endl;
			cout << argv[0] << " <source> <destination> [/A] [/D] [E] [/F] [/I] [/M] [/O]" << endl;
			cout << "[/Q] [/R] [/S] [/W]" << endl << endl;
			cout << " source Specifies the folder with the file(s) to copy." << endl;
			cout << " destinationSpecifies were the file(s) should be copied to." << endl;
			cout << " /A Sets the destination files(a) to achive attribute." << endl;
			cout << " /D When set only folders structures are created." << endl;
			cout << " /E Create folder structures and zero-length files only." << endl;
			cout << " /F When set displays the full filename being copied." << endl;
			cout << " /I When set file status is shown." << endl;
			cout << " /M Move files (delete from source after copying)." << endl;
			cout << " /O Writes over files that are read-only." << endl;
			cout << " /Q When set no messages are displayed while copying." << endl;
			cout << " /R Include full relative paths in destination path." << endl;
			cout << " /S When set all sub folders are included in backup." << endl;
			cout << " /W Displays a message and waits for a key press." << endl;
			cout << endl;
			exit(1);
		}
		exit(1);
	}
	//
	//Check argv
	if (argc < 3){
		cout << "Usage: " << argv[0] << " <source> <destination> [options]" << endl << endl;
		cout << "For more information see " << argv[0] << " /?" << endl;
		exit(1);
	}
	//Get other args
	while (i < argc){
		Flags = LCase(argv[i]);
		//All files attributes are set to achive when set
		if (Flags == "/a"){
			SetAchiveOnlyAttr = true;
		}
		//Create zero length files.
		if (Flags == "/e"){
			ZeroLenFiles = true;
		}
		if (Flags == "/r"){
			IncludeFullRelativePath = true;
		}
		//If set all sub folders are scanned.
		if (Flags == "/s"){
			ScanAllDirs = true;
		}
		//Ovwerwrite read only files.
		if (Flags == "/o"){
			OverReadOnly = true;
		}
		//if set no on-screen messages are shown
		if (Flags == "/q"){
			NoMsg = true;
		}
		//When set only folder structure is created.
		if (Flags == "/d"){
			bCopyFiles = false;
		}
		//Displays full filenames
		if (Flags == "/f"){
			ShowFullName = true;
		}
		//Display file status if set
		if (Flags == "/i"){
			ShowStatusInfo = true;
		}
		//Display a message before copying if set
		if (Flags == "/w"){
			ShowStartMsg = true;
		}
		//Move files
		if (Flags == "/m"){
			m_Action = F_MOVE;
		}
		//INC counter
		i++;
	}
	//Display copying message.
	if (ShowStartMsg){
		cout << "The copy process is about to begin press any key to continue." << endl;
		while (1){
			if (kbhit()){
				break;
			}
		}
	}
	if (ShowStatusInfo){
		sStatusA = "....OK";
		sStatusB = "....Skipped";
	}
	//Source folder
	Temp = argv[1];
	//Destination path
	DeskFolder = FixPath(argv[2]);
	//Include source's path in destination path
	if (IncludeFullRelativePath){
		DeskFolder = FixPath(argv[2]) + Temp[0] + '\\';
	}
	//Check for file type
	pos = Temp.find('*');
	if (pos != string::npos){
		fExt = TrimAll(LCase(Temp.substr(pos + 1)));
		if (fExt == ".*"){
			fExt.clear();
		}
		//Fix the path
		Temp.erase(pos);
		//Trim any remaining spaces
		Temp = TrimAll(Temp);
	}
	else{
		//Default copy all file types.
		Temp = TrimAll(Temp);
	}
	//Call DirTree procedure
	DirTree(Temp, DeskFolder, fExt, ScanAllDirs);
	if (!NoMsg){
		//Display results
		cout << endl;
		//Test if copying filees.
		if (m_Action == F_COPY){
			//Copying files message.
			cout << "Copyed : " << Copyed << endl;
		}
		else{
			//Update message for moving files.
			cout << "Moved : " << Copyed << endl;
		}
		cout << "Skipped : " << Skipped << endl;
	}
	return EXIT_SUCCESS;
}


Other 50 submission(s) by this author

 


Report Bad Submission
Use this form to tell us if this entry should be deleted (i.e contains no code, is a virus, etc.).
This submission should be removed because:

Your Vote

What do you think of this code (in the Beginner category)?
(The code with your highest vote will win this month's coding contest!)
Excellent  Good  Average  Below Average  Poor (See voting log ...)
 

Other User Comments


 There are no comments on this submission.
 

Add Your Feedback
Your feedback will be posted below and an email sent to the author. Please remember that the author was kind enough to share this with you, so any criticisms must be stated politely, or they will be deleted. (For feedback not related to this particular code, please click here instead.)
 

To post feedback, first please login.