/////////////////////////////////////////////////////////////////////// // fileInfo.cpp - manage file information extracted from Win32 API // // ver 2.7 // // Language: Visual C++, ver 8 // // Platform: Dell Dimension 8300, Windows XP Pro, SP2 // // Application: CSE687 Project #1, Spring 2007 // // Author: Jim Fawcett, Syracuse University CST 2-187, // // (315) 443-3948, jfawcett@twcny.rr.com // /////////////////////////////////////////////////////////////////////// #pragma warning(disable : 4786) #include #include #include #include "fileInfo.h" using namespace std; //----< void constructor >------------------------------------- fileInfo::fileInfo() : showSeconds_(false), showTime_(true), showDate_(true), showAttrib_(true) { _CurrPath = _OrigPath = getPath(); } //----< constructor taking path >------------------------------ fileInfo::fileInfo(const string &path) : showSeconds_(false), showTime_(true), showDate_(true), showAttrib_(true) { _OrigPath = getPath(); setPath(path); } // //----< copy constructor >------------------------------------- fileInfo::fileInfo(const fileInfo &fi) { data.dwFileAttributes = fi.data.dwFileAttributes; data.ftCreationTime = fi.data.ftCreationTime; data.ftLastAccessTime = fi.data.ftLastAccessTime; data.ftLastWriteTime = fi.data.ftLastWriteTime; data.nFileSizeHigh = fi.data.nFileSizeHigh; data.nFileSizeLow = fi.data.nFileSizeLow; data.dwReserved0 = fi.data.dwReserved0; data.dwReserved1 = fi.data.dwReserved1; int i; for(i=0; i------------------------------------------- fileInfo::~fileInfo() { setPath(_OrigPath); } //----< assignment operator >---------------------------------- fileInfo& fileInfo::operator=(const fileInfo &fi) { if(this == &fi) return *this; data.dwFileAttributes = fi.data.dwFileAttributes; data.ftCreationTime = fi.data.ftCreationTime; data.ftLastAccessTime = fi.data.ftLastAccessTime; data.ftLastWriteTime = fi.data.ftLastWriteTime; data.nFileSizeHigh = fi.data.nFileSizeHigh; data.nFileSizeLow = fi.data.nFileSizeLow; data.dwReserved0 = fi.data.dwReserved0; data.dwReserved1 = fi.data.dwReserved1; int i; for(i=0; i---------------------------------------- unsigned long int fileInfo::size() const { DWORDLONG myDWL = data.nFileSizeHigh*MAXDWORD + data.nFileSizeLow; return (unsigned long)myDWL; } //----< is my size smaller? >---------------------------------- bool fileInfo::smaller(const fileInfo &fi) const { DWORDLONG myDWL = data.nFileSizeHigh*MAXDWORD + data.nFileSizeLow; DWORDLONG fiDWL = fi.data.nFileSizeHigh*MAXDWORD + fi.data.nFileSizeLow; return (myDWL < fiDWL); } //----< is my size larger? >----------------------------------- bool fileInfo::larger(const fileInfo &fi) const { DWORDLONG myDWL = data.nFileSizeHigh*MAXDWORD + data.nFileSizeLow; DWORDLONG fiDWL = fi.data.nFileSizeHigh*MAXDWORD + fi.data.nFileSizeLow; return (myDWL > fiDWL); } //----< return FILETIME >-------------------------------------- // // typedef struct _FILETIME // { DWORD dwLowDateTime; DWORD dwHighDateTime; } FILETIME; // FILETIME fileInfo::getFILETIME() { FILETIME lft; FileTimeToLocalFileTime(&data.ftLastWriteTime,&lft); return lft; } //----< compare file times >----------------------------------- // // returns 1 if my FILETIME is later than ft // 0 if my FILETIME equals ft // -1 if my FILETIME is earlier than ft // int fileInfo::compareFileTime(FILETIME& ft) { FILETIME myft = getFILETIME(); return (int)::CompareFileTime(&myft,&ft); } // //----< private date and time extraction >--------------------- SYSTEMTIME fileInfo::DateAndTime() const { SYSTEMTIME st; FILETIME lft; FileTimeToLocalFileTime(&data.ftLastWriteTime,&lft); FileTimeToSystemTime(&lft,&st); return st; } //----< get file date string >--------------------------------- string fileInfo::date() const { SYSTEMTIME st = DateAndTime(); string date; date.resize(0); date += '0' + (st.wMonth / 10); date += '0' + (st.wMonth % 10); date += '/'; date += '0' + (st.wDay / 10); date += '0' + (st.wDay % 10); date += '/'; int tmp = st.wYear; date += '0' + (tmp/1000); tmp %= 1000; date += '0' + (tmp / 100); tmp %= 100; date += '0' + (tmp / 10); tmp %= 10; date += '0' + (tmp); return date; } //----< get file time string >--------------------------------- string fileInfo::time() const { SYSTEMTIME st = DateAndTime(); string time; string AMPM = "am"; if(st.wHour > 12) { st.wHour -= 12; AMPM = "pm"; } time.erase(); time += '0' + (st.wHour / 10); time += '0' + (st.wHour % 10); time += ':'; time += '0' + (st.wMinute / 10); time += '0' + (st.wMinute % 10); if(showSeconds_) { time += ':'; time += '0' + (st.wSecond / 10); time += '0' + (st.wSecond % 10); } time += " "; time += AMPM; return time; } // //----< make attributes string >------------------------------- string fileInfo::attributes() const { string temp; if(isArchive() ) temp += 'A'; if(isCompressed()) temp += 'C'; if(isDirectory() ) temp += 'D'; if(isEncrypted() ) temp += 'E'; if(isHidden() ) temp += 'H'; if(isOffLine() ) temp += 'O'; if(isReadOnly() ) temp += 'R'; if(isSystem() ) temp += 'S'; if(isTemporary() ) temp += 'T'; return temp; } //----< pragma needed to disable performance warning >--------- // // for some reason casts don't inhibit warning as they should #pragma warning(disable : 4800) //----< is this file Archive? >-------------------------------- bool fileInfo::isArchive() const { return (data.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE); } //----< is this file Compressed? >----------------------------- bool fileInfo::isCompressed() const { return (data.dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED); } //----< is this file Directory? >------------------------------ bool fileInfo::isDirectory() const { return (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY); } // //----< is this file Encrypted? >------------------------------ bool fileInfo::isEncrypted() const { return (data.dwFileAttributes & FILE_ATTRIBUTE_ENCRYPTED); } //----< is this file Hidden? >--------------------------------- bool fileInfo::isHidden() const { return (data.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN); } //----< is this file Normal? >--------------------------------- bool fileInfo::isNormal() const { return (data.dwFileAttributes & FILE_ATTRIBUTE_NORMAL); } //----< is this file OffLine? >-------------------------------- bool fileInfo::isOffLine() const { return (data.dwFileAttributes & FILE_ATTRIBUTE_OFFLINE); } //----< is this file ReadOnly? >------------------------------- bool fileInfo::isReadOnly() const { return (data.dwFileAttributes & FILE_ATTRIBUTE_READONLY); } //----< is this file System? >--------------------------------- bool fileInfo::isSystem() const { return (data.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM); } //----< is this file Temporary? >------------------------------ bool fileInfo::isTemporary() const { return (data.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY); } // //----< display line of file data >---------------------------- void fileInfo::showData(ostream &out, char ch, int width) const { out << " " << setw(width) << name(); if(showSize_) out << setw(10) << size(); if(showDate_) out << " " << date(); if(showTime_ && showDate_) out << " " << time(); if(showAttrib_) out << " " << attributes(); out << ch; } //----< get current searchPath >------------------------------- // // fill with current directory path if empty // string fileInfo::getPath() { char buffer[256]; ::GetCurrentDirectory(256,buffer); return std::string(buffer); } //----< set current directory >-------------------------------- void fileInfo::setPath(const string& s) { if(::SetCurrentDirectory(s.c_str()) == 0) { string temp = s + " - path not found"; throw invalid_argument(temp.c_str()); } _CurrPath = s; } //----< find first file >-------------------------------------- bool fileInfo::firstFile(const string &filePattern) { string path = getPath(); if(path[path.size()-1] != '\\') path += '\\'; path += filePattern; _handle = ::FindFirstFile(path.c_str(),&data); return (_handle != INVALID_HANDLE_VALUE); } //----< find next file >--------------------------------------- bool fileInfo::nextFile() { if(_handle == INVALID_HANDLE_VALUE) return false; return (::FindNextFile(_handle,&data) == TRUE); } //----< close search for current file >------------------------ void fileInfo::closeFile() { FindClose(_handle); } // //----< function object which detects date order >------------- class earlier { public: bool operator()(const fileInfo &fi1, const fileInfo &fi2) { return fi1.earlier(fi2); } }; //----< function object which detects size order >------------- class smaller { public: bool operator()(const fileInfo &fi1, const fileInfo &fi2) { return fi1.smaller(fi2); } }; //----< test stub >-------------------------------------------- #ifdef TEST_FILEINFO //----< test entry point >------------------------------------- void main(int argc, char *argv[]) { cout << "\n Testing Fileinfo objects " << "\n ==========================\n"; typedef set< fileInfo, less > setNames; // names are unique typedef multiset< fileInfo, earlier > setDates; // dates may not be typedef multiset< fileInfo, smaller > setSizes; // sizes may not be fileInfo f; f.showSeconds(true); try { if(argc > 1) f.setPath(argv[1]); } catch(exception& e) { cout << "\n\n " << e.what() << "\n\n"; f.setPath(".."); } cout << "\n path = " << f.getPath() << endl; // cout << "\n Files in FindNextFile Order\n"; setNames sn; setDates sd; setSizes ss; if(!f.firstFile("*.*")) return; sn.insert(f); sd.insert(f); ss.insert(f); f.showData(cout); while(f.nextFile()) { sn.insert(f); sd.insert(f); ss.insert(f); f.showData(cout); } f.closeFile(); cout << "\n Files ordered alphabetically:\n"; setNames::iterator fnIt; for(fnIt = sn.begin(); fnIt != sn.end(); fnIt++) { fnIt->showData(cout); } cout << "\n Files ordered by date:\n"; setDates::iterator fdIt; for(fdIt = sd.begin(); fdIt != sd.end(); fdIt++) { fdIt->showData(cout); } cout << "\n Files ordered by size:\n"; setSizes::iterator fsIt; for(fsIt = ss.begin(); fsIt != ss.end(); fsIt++) { fsIt->showData(cout); } cout << "\n\n"; cout << "\n Comparing file times:\n"; setDates::iterator first = sd.begin(); setDates::iterator second = first; ++second; cout << "\n " << (*first).name() << " has date: " << (*first).date() << ", " << (*first).time(); cout << "\n " << (*second).name() << " has date: " << (*second).date() << ", " << (*second).time(); int retVal = (*first).compareFileTime((*second).getFILETIME()); if(retVal > 0) cout << "\n " << (*first).name() << " is later than " << (*second).name(); if(retVal == 0) cout << "\n " << (*first).name() << " is same time as " << (*second).name(); if(retVal < 0) cout << "\n " << (*first).name() << " is earlier than " << (*second).name(); // retVal = (*second).compareFileTime((*first).getFILETIME()); if(retVal > 0) cout << "\n " << (*second).name() << " is later than " << (*first).name(); if(retVal == 0) cout << "\n " << (*second).name() << " is same time as " << (*first).name(); if(retVal < 0) cout << "\n " << (*second).name() << " is earlier than " << (*first).name(); retVal = (*first).compareFileTime((*first).getFILETIME()); if(retVal > 0) cout << "\n " << (*first).name() << " is later than " << (*first).name(); if(retVal == 0) cout << "\n " << (*first).name() << " is same time as " << (*first).name(); if(retVal < 0) cout << "\n " << (*first).name() << " is earlier than " << (*first).name(); cout << "\n\n Last search path = " << f.lastSetPath(); cout << "\n\n"; } #endif