标签:自定义函数库
自定义的常用文件与目录操作函数库,在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