标签:自定义函数库
自定义的常用文件与目录操作函数库,在win和linux平台做了跨平台的处理。(跨平台的处理可以作为参考比较。在win下目录的符号可以是\或者/,但是在linux下只能是/。)
下面给出的是源文件,实现接口函数的代码。每个接口函数都有很详细的功能说明。
/* 判断文件或目录是否存在bool FileUtil::FileExists(LPCTSTR sFilePath) { #if PLATFORM == WINDOWS32 || PLATFORM == WINDOWS64 DWORD dwAttr = GetFileAttributes(sFilePath); if ( dwAttr == (DWORD)-1 ) return false; else return true; #endif #if PLATFORM == LINUX32 || PLATFORM == LINUX64 struct stat file; int res = stat(sFilePath, &file); if(-1 != res && S_ISREG(file.st_mode)) { return true; } else return false; #endif }
bool FileUtil::IsArchive(LPCTSTR sFilePath) { #if PLATFORM == WINDOWS32 || PLATFORM == WINDOWS64 DWORD dwAttr = GetFileAttributes(sFilePath); if ( dwAttr == (DWORD)-1 || (dwAttr & FILE_ATTRIBUTE_ARCHIVE) == 0 ) return false; else return true; #endif #if PLATFORM == LINUX32 || PLATFORM == LINUX64 //简单判断文件是否存在 struct stat file; int res = stat(sFilePath, &file); if(-1 != res && S_ISREG(file.st_mode)) { return true; } else return false; #endif }
bool FileUtil::IsDirectory(LPCTSTR sDirPath) { #if PLATFORM == WINDOWS32 || PLATFORM == WINDOWS64 DWORD dwAttr = GetFileAttributes(sDirPath); if ( dwAttr == (DWORD)-1 || (dwAttr & FILE_ATTRIBUTE_DIRECTORY) == 0 ) return false; else return true; #endif #if PLATFORM == LINUX32 || PLATFORM == LINUX64 struct stat file; int res = stat(sDirPath, &file); if(-1 != res && S_ISDIR(file.st_mode)) { return true; } return false; #endif }
SIZE_T FileUtil::ExtractFileName(LPCTSTR sFilePath, LPTSTR sNameBuf, SIZE_T dwBufLen) { LPCTSTR sNameStart, sNameEnd = sFilePath + _tcslen(sFilePath) - 1; //跳过目录名称后连续的'/'或'\' while ( sNameEnd >= sFilePath && (*sNameEnd == '/' || *sNameEnd == '\\') ) { sNameEnd--; } sNameStart = sNameEnd; sNameEnd++; //定位目录名称起始的位置 while ( sNameStart >= sFilePath ) { if ( *sNameStart == '/' || *sNameStart == '\\' ) break; sNameStart--; } sNameStart++; //拷贝目录名称 if ( sNameStart < sNameEnd ) { SIZE_T dwNameLen = sNameEnd - sNameStart; if ( dwBufLen > 0 ) { if ( dwBufLen > dwNameLen ) dwBufLen = dwNameLen; else dwBufLen--; memcpy(sNameBuf, sNameStart, sizeof(*sNameStart) * dwBufLen); sNameBuf[dwBufLen] = 0; } return dwNameLen; } return 0; }
SIZE_T FileUtil::ExtractFileNameOnly(LPCTSTR sFileName, LPTSTR sNameBuf, SIZE_T dwBufLen) { //文件名为空则直接返回0 if ( !*sFileName ) { if ( dwBufLen > 0 ) sNameBuf[0] = 0; return 0; } LPCTSTR sNameStart, sNameEnd = sFileName + _tcslen(sFileName) - 1; //如果文件是目录 if ( *sNameEnd == '/' || *sNameEnd == '\\' ) { //跳过目录名称后连续的'/'或'\' while ( sNameEnd >= sFileName && (*sNameEnd == '/' || *sNameEnd == '\\') ) { sNameEnd--; } sNameEnd++; } else { LPCTSTR sPtr = sNameEnd; //找到文件后缀部分的起始位置 while ( sPtr >= sFileName ) { if (*sPtr == '.') { sNameEnd = sPtr; break; } if (*sPtr == '/' || *sPtr == '\\') break; } } sNameStart = sNameEnd - 1; //定位目录名称起始的位置 while ( sNameStart >= sFileName ) { if ( *sNameStart == '/' || *sNameStart == '\\' ) break; sNameStart--; } sNameStart++; //拷贝目录名称 if ( sNameStart < sNameEnd ) { SIZE_T dwNameLen = sNameEnd - sNameStart; if ( dwBufLen > 0 ) { if ( dwBufLen > dwNameLen ) dwBufLen = dwNameLen; else dwBufLen--; memcpy(sNameBuf, sNameStart, sizeof(*sNameStart) * dwBufLen); sNameBuf[dwBufLen] = 0; } return dwNameLen; } return 0; }
LPCTSTR FileUtil::ExtractFileExt(LPCTSTR sFileName) { LPCTSTR sResult = NULL; while (*sFileName) { if (*sFileName == '.') sResult = sFileName; sFileName++; } return sResult; }
SIZE_T FileUtil::ExtractFileDirectory(LPCTSTR sFilePath, LPTSTR sDirBuf, SIZE_T dwBufLen) { LPCTSTR sDirEnd = sFilePath + _tcslen(sFilePath) - 1; while (sDirEnd >= sFilePath && *sDirEnd != '/' && *sDirEnd != '\\') { sDirEnd--; } if ( sDirEnd > sFilePath ) { SIZE_T dwNameLen = sDirEnd - sFilePath; if ( dwBufLen > 0 ) { if ( dwBufLen > dwNameLen ) dwBufLen = dwNameLen; else dwBufLen--; memcpy(sDirBuf, sFilePath, sizeof(*sDirBuf) * dwBufLen); sDirBuf[dwBufLen] = 0; } return dwNameLen; } return 0; }
SIZE_T FileUtil::ExtractTopDirectoryName(LPCTSTR sDirPath, OUT LPCTSTR *ppChildDirPath, LPTSTR sDirName, SIZE_T dwBufLen) { LPCTSTR sNameEnd; //跳过目录名称前连续的'/'或'\' while ( *sDirPath && (*sDirPath == '/' || *sDirPath == '\\') ) { sDirPath++; } sNameEnd = sDirPath; //定位目录名称起始的位置 while ( *sNameEnd ) { if ( *sNameEnd == '/' || *sNameEnd == '\\' ) break; sNameEnd++; } //拷贝目录名称 if ( sNameEnd > sDirPath ) { SIZE_T dwNameLen = sNameEnd - sDirPath; if ( dwBufLen > 0 ) { if ( dwBufLen > dwNameLen ) dwBufLen = dwNameLen; else dwBufLen--; memcpy(sDirName, sDirPath, sizeof(*sDirPath) * dwBufLen); sDirName[dwBufLen] = 0; if (ppChildDirPath) *ppChildDirPath = sNameEnd; } return dwNameLen; } return 0; }
bool FileUtil::DeepCreateDirectory(LPCTSTR sDirPath) { TCHAR sPath[4096]; LPTSTR sPathPtr = sPath; SIZE_T dwNameLen, dwBufLen = ArrayCount(sPath) - 1; DWORD dwAttr; while (true) { dwNameLen = ExtractTopDirectoryName(sDirPath, &sDirPath, sPathPtr, dwBufLen);//获取顶层目录名称* (abc\efg\ --> abc) //如果目录名称长度超过目录缓冲区长度则放弃 if ( dwNameLen >= dwBufLen ) return false; //如果目录名称长度为0则表示所有目录均已创建完成 if (dwNameLen == 0) return true; sPathPtr += dwNameLen; #if PLATFORM == WINDOWS32 || PLATFORM == WINDOWS64 //如果目录名称不是驱动器名称则检查和创建目录 if (sPathPtr[-1] != ':') { //如果目录不存在则创建此目录 dwAttr = GetFileAttributes(sPath); if ( (dwAttr == (DWORD)-1 && GetLastError() == ERROR_FILE_NOT_FOUND) ) { if (!CreateDirectory(sPath, NULL)) return false; } //如果文件存在且文件不是目录则返回false else if ( !(dwAttr & FILE_ATTRIBUTE_DIRECTORY) ) { return false; } } #endif #if PLATFORM == LINUX32 || PLATFORM == LINUX64 struct stat fileStat; if(-1 == stat(sPath, &fileStat))//没有该文件或目录 { if(ENOENT == errno)//错误码是 ENOENT: No such file or directory { if(-1 == mkdir(sPath, S_IRWXG))//创建一层目录 { return false; } } } #endif sPathPtr[0] = '/'; sPathPtr++; if ( dwBufLen > dwNameLen ) dwBufLen -= dwNameLen + 1; else dwBufLen = 0; } return false; }
其中的一些自定义的宏定义和类型定义如下:
由于跨平台的原因的自定义宏(使用时,没有跨平台需要的话,可删除不需要的部分)
#define _tcslen(STR) strlen(STR)
typedef const char *LPCTSTR, *LPCSTR;
typedef size_t SIZE_T;
其他的宏
获取数组长度
#define ArrayCount(a)(sizeof(a)/sizeof((a)[0]))
标签:自定义函数库
原文地址:http://blog.csdn.net/chenjiayi_yun/article/details/44751081