///////////////////////////////////////////////////////////////////////////// // FileSystem.cpp - Support file and directory operations // // ver 1.1 // // Language: Visual C++, Visual Studio 2008 // // Platform: Dell Precision T7400, Quad core Xeons, Vista Ultimate, SP1 // // Application: CSE687 - OOD, demonstration, Spring 2009 // // Author: Jim Fawcett, CST 4-187, Syracuse University // // (315) 443-3948, jfawcett@twcny.rr.com // ///////////////////////////////////////////////////////////////////////////// #include #include "FileSystem.h" using namespace WinTools_Extracts; //----< File constructor opens file stream >------------------------------- File::File(const std::string& filespec, direction dirn, type typ) : name_(filespec), blockSize_(1024), pIStream(0), pOStream(0), dirn_(dirn), typ_(typ) { if(dirn == in) { pIStream = new std::ifstream; if(typ == binary) pIStream->open(filespec.c_str(), std::ios::in | std::ios::binary); else pIStream->open(filespec.c_str(), std::ios::in); } else { pOStream = new std::ofstream; if(typ == binary) pOStream->open(filespec.c_str(), std::ios::out | std::ios::binary); else pOStream->open(filespec.c_str(), std::ios::out); } } //----< File destructor closes file stream >------------------------------- File::~File() { if(pIStream) { pIStream->close(); delete pIStream; } if(pOStream) { pOStream->close(); delete pOStream; } } //----< reads one line of a text file >------------------------------------ std::string File::getLine() { if(typ_ == binary) throw std::exception("binary file"); const int BufSize = 255; char buffer[BufSize]; pIStream->getline(buffer,BufSize); return std::string(buffer); } //----< writes one line of a text to a file >------------------------------ void File::putLine(const std::string& s) { if(typ_ == binary) throw std::exception("binary file"); for(size_t i=0; iput(s[i]); pOStream->flush(); } //----< reads a block of bytes from binary file >-------------------------- File::block File::getBlock() { block blk; if(pIStream) { for(size_t i=0; iget(); if(pIStream->good()) blk.push_back(b); else break; } } return blk; } //----< writes a block of bytes to binary file >--------------------------- void File::putBlock(File::block blk) { if(!pOStream->good()) return; for(size_t i=0; iput(blk[i]); } } //----< tests for error free stream state >-------------------------------- bool File::isGood() { if(pIStream) return pIStream->good(); if(pOStream) return pOStream->good(); return false; } //----< flushes output stream to its file >-------------------------------- void File::flush() { if(pOStream) pOStream->flush(); if(pOStream) return; } //----< clears error state enabling operations again >--------------------- void File::clear() { if(pIStream) pIStream->clear(); if(pOStream) pOStream->clear(); } //----< close file handle >------------------------------------------------ void File::close() { File::flush(); if(pIStream) pIStream->close(); if(pOStream) pOStream->close(); } //----< convert relative path to full path >------------------------------- std::string FileHandler::getFullPath(const std::string& filespec) { ::GetFullPathNameA(filespec.c_str(),BufSize,buffer,NULL); return std::string(buffer); } //----< extract, possibly relative, path from filespec >------------------- std::string FileHandler::getPath(const std::string& filespec) { std::string temp(filespec); size_t pos = temp.find_last_of('\\'); if(pos >= temp.size()) { pos = temp.find_last_of('/'); if(pos >= temp.size()) return "."; } return temp.substr(0,pos+1); } //----< get file name part of path string >-------------------------------- std::string FileHandler::getFileName(const std::string& filespec) { char* pTempBuffer = 0; ::GetFullPathNameA(filespec.c_str(),BufSize,buffer,(LPSTR*)&pTempBuffer); if(pTempBuffer) return std::string(pTempBuffer); return std::string(""); } //----< return name of the current directory >----------------------------- std::string FileHandler::getCurrentDirectory() { ::GetCurrentDirectoryA(BufSize,buffer); return std::string(buffer); } //----< change the current directory to path >----------------------------- void FileHandler::setCurrentDirectory(const std::string& path) { ::SetCurrentDirectoryA(path.c_str()); } //----< get directory seperator character >-------------------------------- char FileHandler::getSeperatorChar(const std::string& path) { if(path.find_first_of('\\') < path.size()) return '\\'; else if(path.find_first_of('/') < path.size()) return '/'; return '\\'; } //----< get fully qualified names of files >------------------------------- std::vector FileHandler::getFileSpecs( const std::string& inpath, const std::string& inpattern ) { std::string path = getFullPath(inpath); char sepChar = getSeperatorChar(path); if(path.size() > 0) { char lastChar = path[path.size()-1]; if(lastChar != sepChar) path += sepChar; } std::string pattern = path + inpattern; std::vector files; HANDLE hFindFile = ::FindFirstFileA(pattern.c_str(),pFindFileData); if(hFindFile != INVALID_HANDLE_VALUE) { if(!(pFindFileData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) files.push_back(path + pFindFileData->cFileName); while(::FindNextFileA(hFindFile,pFindFileData)) { if(!(pFindFileData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) files.push_back(path + pFindFileData->cFileName); } } ::FindClose(hFindFile); return files; } //----< get fully qualified names of subdirectories >---------------------- std::vector FileHandler::getSubDirectorySpecs( const std::string& inpath, const std::string& inpattern ) { std::string path = getFullPath(inpath); for(size_t i=0; i 0) { char lastChar = path[path.size()-1]; if(lastChar != '\\') path += '\\'; } std::string pattern = path + inpattern; std::vector files; HANDLE hFindFile = ::FindFirstFileA(pattern.c_str(),pFindFileData); if(hFindFile != INVALID_HANDLE_VALUE) { if(pFindFileData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) files.push_back(path + pFindFileData->cFileName); while(::FindNextFileA(hFindFile,pFindFileData)) { if(pFindFileData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) files.push_back(path + pFindFileData->cFileName); } } ::FindClose(hFindFile); return files; } //----< get names of all the files matching pattern (path:name) >---------- std::vector FileHandler::getFiles(const std::string& pattern) { std::vector files; HANDLE hFindFile = ::FindFirstFileA(pattern.c_str(),pFindFileData); if(hFindFile != INVALID_HANDLE_VALUE) { if(!(pFindFileData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) files.push_back(pFindFileData->cFileName); while(::FindNextFileA(hFindFile,pFindFileData)) { if(!(pFindFileData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) files.push_back(pFindFileData->cFileName); } } ::FindClose(hFindFile); return files; } //----< get names of all directories matching pattern (path:name) >-------- std::vector FileHandler::getDirectories(const std::string& pattern) { std::vector dirs; HANDLE hFindFile = ::FindFirstFileA(pattern.c_str(),pFindFileData); if(hFindFile != INVALID_HANDLE_VALUE) { if(pFindFileData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) dirs.push_back(pFindFileData->cFileName); while(::FindNextFileA(hFindFile,pFindFileData)) { if(pFindFileData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) dirs.push_back(pFindFileData->cFileName); } } ::FindClose(hFindFile); return dirs; } //----< test stub >-------------------------------------------------------- #ifdef TEST_FILESYSTEM void title(const std::string& title, char ch='=') { std::cout << "\n " << title; std::cout << "\n " << std::string(title.size()+2, ch); } int main(int argc, char* argv[]) { title("Demonstrate FileHandler class"); // Display contents of current directory FileHandler fh; std::vector tempfiles = fh.getFileSpecs("c:\\temp", "*.*"); if(tempfiles.size() > 0) { std::cout << "\n first file found in C:\\temp: " << tempfiles[0]; std::cout << "\n its path: " << fh.getPath(tempfiles[0]); std::cout << "\n its name: " << fh.getFileName(tempfiles[0]) << std::endl; } std::cout << "\n current directory is:\n " << fh.getCurrentDirectory(); std::cout << "\n it contains files:"; std::vector currfiles = fh.getFiles(); for(size_t i=0; i currdirs = fh.getDirectories(); for(size_t i=0; i