VB icon

Folder Backup tool

Email
Submitted on: 9/13/2016 8:19:21 PM
By: Ben  
Level: Beginner
User Rating: Unrated
Compatibility: C++ (general), Microsoft Visual C++
Views: 1356
 
     Here is a new version of my file copying tool, this version now supports many options such as keeping file arributes, keeping the date and time of the file, also in built help system using the help switch /? program better way of backing up file types. and more hope you like the update please comment note tested on Windows only.
 
code:
Can't Copy and Paste this?
Click here for a copy-and-paste friendly version of this code!
				
//**************************************
// Name: Folder Backup tool
// Description:Here is a new version of my file copying tool, this version now supports many options such as keeping file arributes, keeping the date and time of the file, also in built help system using the help switch /? program better way of backing up file types. and more hope you like the update please comment note tested on Windows only.
// By: Ben
//**************************************

// Folder Copy
// Version 1.1 (build 2)
// Ben DreamVB
#include <iostream>
#include <Windows.h>
using namespace std;
using std::cout;
using std::endl;
string LCase(const string& src)
{
	string dest(src);
	for (char& ch : dest)
		ch = tolower (ch);
	return dest;
}
string FixPath(string src){
	if (src[src.length() - 1] != '\\'){
		return src + "\\";
	}
	return src;
}
bool DirExists(string Folder){
	//Check if a file was found.
	if ((GetFileAttributesA(Folder.c_str()) & FILE_ATTRIBUTE_DIRECTORY)){
		return false;
	}
	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 MyFileCopy(string src, string dest, int chunksize, bool KeepDate = false){
	FILE *fin = NULL;
	FILE *fout = NULL;
	char *Buffer = NULL;
	size_t BytesRead = 0;
	rsize_t BytesWrite = 0;
	//Do a stright windows copy using system api calls.
	if (KeepDate){
		if (!CopyFileA(src.c_str(), dest.c_str(), false)){
			return false;
		}
		else{
			return true;
		}
	}
	//Do block custom copy
	//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;
}
int main(int argc, char *argv[]){
	//Backup files from one folder to the other.
	char DirName[_MAX_PATH];
	//Tools variables
	DWORD fAttr = 0;
	int pos = 0;
	int Copied = 0;
	int Skipped = 0;
	int cpychunksize = 1024;
	bool CanCopy = true;
	bool SetArrib = false;
	//Folder and files variables
	string sSrcFolder = "";
	string sDestFolder = "";
	string DestFile = "";
	string SrcFile = "";
	string ScanSrcDir = "";
	string sFileType = "";
	//Program arguments
	int parms = 3;
	bool Qmode = false;
	bool StopOnError = true;
	bool ShowFullNames = false;
	bool KeepDateTime = false;
	string sSwitch = "";
	//Find file variables
	HANDLE f = 0;
	WIN32_FIND_DATAA wfd;
	if (argc == 2){
		sSwitch = LCase(argv[1]);
		//Display online help
		if (sSwitch == "/?"){
			cout << "Copies files from one directory to another." << endl << endl;
			cout << argv[0] << " <source> <destination> [/CS:chunksize] [/A] [/C] [/D] [/F] [/Q]" << endl;
			cout << endl;
			cout << " SourceSpecifies the folder to copy the files from." << endl;
			cout << " destinationSpecifies the folder to copy the files to." << endl;
			cout << " /ACreate destination files with source files attributes." << endl;
			cout << " /CContinues copying even if errors occur." << endl;
			cout << " /CSets destination file attributes and date and time from" << endl;
			cout << "original source. uses WinAPI for copying the files." << endl;
			cout << " /FDisplay full filenames of source and destination while copying." << endl;
			cout << " /QDoes not display file names while copying." << endl;
		}
		return 0;
	}
	if (argc < 3){
		cout << "Usage: " << argv[0] << " <Source> <destination> [OPTIONS]" << endl << endl;
		cout << "For more information type " << argv[0] << " /?" << endl;
		exit(1);
	}
	while (parms < argc){
		if (argv[parms][0] == '/'){
			sSwitch = LCase(argv[parms]);
			//Check for : in switch
			pos = sSwitch.find(':');
			if (pos != string::npos){
				//Check for chunksize for the file copy function.
				if (sSwitch.substr(1, pos - 1) == "cs"){
					cpychunksize = atoi(sSwitch.substr(pos + 1).c_str());
					if (cpychunksize == 0){
						cpychunksize = 1024;
					}
				}
				//End of chunk size code
			}
			else{
				//Quite mode. does not display messages.
				if (sSwitch == "/q"){
					Qmode = true;
				}
				//Contine if copy errors are found.
				if (sSwitch == "/c"){
					StopOnError = false;
				}
				//Show fulll source and dest filenames while copying
				if (sSwitch == "/f"){
					ShowFullNames = true;
				}
				if (sSwitch == "/a"){
					SetArrib = true;
				}
				if (sSwitch == "/d"){
					KeepDateTime = true;
				}
			}
		}
		parms++;
	}
	//Get source folder
	strcpy(DirName, argv[1]);
	sSrcFolder = DirName;
	//Get dest folder
	strcpy(DirName, argv[2]);
	sDestFolder =FixPath(DirName);
	//Get last folder name from source path.
	pos = sSrcFolder.find('*');
	//If last ends with backslash set on all files.
	if (sSrcFolder[sSrcFolder.length() - 1] == '\\'){
		sFileType = "";
	}
	else if (pos != string::npos){
		sFileType = sSrcFolder.substr(pos + 1);
		//Fix path remove file type *.ext
		sSrcFolder.erase(pos);
	}
	else{
		//Append backslash and set to scan all files.
		sSrcFolder = FixPath(sSrcFolder);
		sFileType = "";
	}
	//Scanning for all files *.*
	if (sFileType == ".*"){
		sFileType = "";
	}
	if (sSrcFolder[sSrcFolder.length() - 1] == '\\'){
		if (!DirExists(sDestFolder)){
			//Create destination folder.
			MyCreateDir(sDestFolder);
		}
		//Scan all files from source folder.
		ScanSrcDir = sSrcFolder + "*.*";
		if (!Qmode){
			//Output source and destination paths
			cout << "Source: " << sSrcFolder.c_str() << endl;
			cout << "Destination : " << sDestFolder.c_str() << endl << endl;
		}
		//Get the first file.
		f = FindFirstFileA(ScanSrcDir.c_str(), &wfd);
		//Check for inaild return.
		if (f == INVALID_HANDLE_VALUE){
			cout << "Error scanning...." << sSrcFolder.c_str() << endl;
			exit(1);
		}
		//Gets the files.
		while (FindNextFileA(f, &wfd) != false){
			if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY){
				//Left for folders
				//Maybe I update this to scan sub folders to.
			}
			else{
				CanCopy = false;
				//Set input and output filenames
				SrcFile = sSrcFolder + wfd.cFileName;
				DestFile = sDestFolder + wfd.cFileName;
				//Get src file attrib
				fAttr = GetFileAttributesA(SrcFile.c_str());
				
				//Get file type
				if (!sFileType.length() == 0){
					//Get last dot in path
					pos = SrcFile.find_last_of('.');
					if (pos != string::npos){
						//Compare file types.
						if (LCase(SrcFile.substr(pos)) == sFileType){
							//Yes file type found we can copy.
							CanCopy = true;
						}
					}
				}
				else{
					//Set copy for all file types.
					CanCopy = true;
				}
				if (CanCopy){
					//Copy files over to sDestFolder
					if (!MyFileCopy(SrcFile.c_str(), DestFile.c_str(), cpychunksize, KeepDateTime)){
						//Test for quite mode
						if (!Qmode){
							//Show full sorce and destination filenames
							if (ShowFullNames){
								cout << "Source : " << SrcFile.c_str() << endl <<
									"Destination : " << DestFile.c_str() << endl <<
									"Status: : Faild" << endl << endl;
							}
							else{
								//Show filename only
								cout << wfd.cFileName << " ...Faild" << endl;
							}
							
							//INC skipped files
							Skipped++;
						}
						//Stop on errors
						if (StopOnError){
							break;
						}
					}
					else{
						if (!KeepDateTime){
							//Check if setting file attrib
							if (SetArrib){
								SetFileAttributesA(DestFile.c_str(), fAttr);
							}
						}
						//Test for quite mode
						if (!Qmode){
							//Show full sorce and destination filenames
							if (ShowFullNames){
								cout << "Source : " << SrcFile.c_str() << endl <<
									"Destination : " << DestFile.c_str() << endl <<
									"Status: : OK" << endl << endl;
							}
							else{
								//Output ok copy message.
								cout << wfd.cFileName << " ...OK" << endl;
							}
							//INC copied counter.
							Copied++;
						}
					}
				}
			}
		}
		//Close
		FindClose(f);
		//Test for quite mode
		if (!Qmode){
			//Output the number of copyied and skipped files.
			cout << endl;
			cout << "Files Coppied : " << Copied << endl;
			cout << "Files 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.