您的位置:首页 > 其它

Windows下使用_access和_stat判断文件和目录是否存在的区别

2016-09-21 14:01 585 查看
  判断一个文件和目录是否存在,可以使用_access或者_stat函数,但是要注意两点:

_access能检测给定路径是否存在,但是无法区分这个路径是文件路径还是目录路径。比如指定路径d:\123,如果D盘下存在文件名为123的文件或者目录名为123的目录,_access返回信息都是存在的,但是无法区分这个路径是文件路径还是目录路径。_stat函数则能正确区分文件还是目录。
路径末尾是否能带有反斜杠“\”对于检测的结果也是不一样的:
末尾是否能有"\"盘符目录文件
本地网络本地网络UNC本地网络UNC
_access无影响无影响无影响无影响无影响不能有"\"无影响无影响
_stat必须有"\"必须有"\"不能有"\"不能有"\"不能有"\"不能有"\"不能有"\"不能有"\"
  以下是我写的测试程序来进行测试和结果,d:\123和t:\123是文件,d:\456和t:\456是目录,t盘是映射的\\172.16.254.101\d$\Lilong\tapefile\共享盘:

#include <cstdio>
#include  <stdio.h>
#include  <stdlib.h>
#include  <io.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <Windows.h>

void Test(char strPath[])
{
printf("%s\n", strPath);
int nRet = _access(strPath, 0);
int nErrNo = errno;

printf("_access:nRet = %d, nErrNo = %d, LastErr = %d\n", nRet, nErrNo, GetLastError());

struct _stat buf = {0};
nRet = _stat(strPath, &buf);
nErrNo = errno;
printf("_stat:nRet = %d, nErrNo = %d, LastErr = %d, _S_IFDIR=%x, _S_IFREG=%x\n\n",
nRet, nErrNo, GetLastError(), buf.st_mode & _S_IFDIR, buf.st_mode & _S_IFREG);
}

int main(int argc, char* argv[])
{
Test("");
Test("d");
Test("d:");
Test("d:\\");
Test("d:\\\\");
Test("d:\\123");
Test("d:\\123\\");
Test("d:\\123\\\\");
Test("d:\\456");
Test("d:\\456\\");
Test("d:\\456\\\\");
Test("t");
Test("t:");
Test("t:\\");
Test("t:\\123");
Test("t:\\123\\");
Test("t:\\456");
Test("t:\\456\\");
Test("\\\\172.16.254.101\\d$\\Lilong\\tapefile");
Test("\\\\172.16.254.101\\d$\\Lilong\\tapefile\\");
Test("\\\\172.16.254.101\\d$\\Lilong\\tapefile\\123");
Test("\\\\172.16.254.101\\d$\\Lilong\\tapefile\\123\\");
Test("\\\\172.16.254.101\\d$\\Lilong\\tapefile\\456");
Test("\\\\172.16.254.101\\d$\\Lilong\\tapefile\\456\\");

return 0;
}


  以下是运行结果:
_access:nRet = -1, nErrNo = 2, LastErr = 3
_stat:nRet = -1, nErrNo = 2, LastErr = 3, _S_IFDIR=0, _S_IFREG=0

d
_access:nRet = -1, nErrNo = 2, LastErr = 2
_stat:nRet = -1, nErrNo = 2, LastErr = 2, _S_IFDIR=0, _S_IFREG=0

d:
_access:nRet = 0, nErrNo = 2, LastErr = 2
_stat:nRet = -1, nErrNo = 2, LastErr = 2, _S_IFDIR=0, _S_IFREG=0

d:\
_access:nRet = 0, nErrNo = 2, LastErr = 2
_stat:nRet = 0, nErrNo = 2, LastErr = 0, _S_IFDIR=4000, _S_IFREG=0

d:\\
_access:nRet = 0, nErrNo = 2, LastErr = 0
_stat:nRet = 0, nErrNo = 2, LastErr = 2, _S_IFDIR=4000, _S_IFREG=0

d:\123
_access:nRet = 0, nErrNo = 2, LastErr = 2
_stat:nRet = 0, nErrNo = 2, LastErr = 2, _S_IFDIR=0, _S_IFREG=8000

d:\123\
_access:nRet = -1, nErrNo = 22, LastErr = 123
_stat:nRet = -1, nErrNo = 2, LastErr = 267, _S_IFDIR=0, _S_IFREG=0

d:\123\\
_access:nRet = -1, nErrNo = 22, LastErr = 123
_stat:nRet = -1, nErrNo = 2, LastErr = 267, _S_IFDIR=0, _S_IFREG=0

d:\456
_access:nRet = 0, nErrNo = 2, LastErr = 267
_stat:nRet = 0, nErrNo = 2, LastErr = 267, _S_IFDIR=4000, _S_IFREG=0

d:\456\
_access:nRet = 0, nErrNo = 2, LastErr = 267
_stat:nRet = -1, nErrNo = 2, LastErr = 2, _S_IFDIR=0, _S_IFREG=0

d:\456\\
_access:nRet = 0, nErrNo = 2, LastErr = 2
_stat:nRet = -1, nErrNo = 2, LastErr = 2, _S_IFDIR=0, _S_IFREG=0

t
_access:nRet = -1, nErrNo = 2, LastErr = 2
_stat:nRet = -1, nErrNo = 2, LastErr = 2, _S_IFDIR=0, _S_IFREG=0

t:
_access:nRet = 0, nErrNo = 2, LastErr = 2
_stat:nRet = -1, nErrNo = 2, LastErr = 2, _S_IFDIR=0, _S_IFREG=0

t:\
_access:nRet = 0, nErrNo = 2, LastErr = 2
_stat:nRet = 0, nErrNo = 2, LastErr = 2, _S_IFDIR=4000, _S_IFREG=0

t:\123
_access:nRet = 0, nErrNo = 2, LastErr = 2
_stat:nRet = 0, nErrNo = 2, LastErr = 2, _S_IFDIR=0, _S_IFREG=8000

t:\123\
_access:nRet = 0, nErrNo = 2, LastErr = 2
_stat:nRet = -1, nErrNo = 2, LastErr = 267, _S_IFDIR=0, _S_IFREG=0

t:\456
_access:nRet = 0, nErrNo = 2, LastErr = 267
_stat:nRet = 0, nErrNo = 2, LastErr = 267, _S_IFDIR=4000, _S_IFREG=0

t:\456\
_access:nRet = 0, nErrNo = 2, LastErr = 267
_stat:nRet = -1, nErrNo = 2, LastErr = 2, _S_IFDIR=0, _S_IFREG=0

\\172.16.254.101\d$\Lilong\tapefile
_access:nRet = 0, nErrNo = 2, LastErr = 2
_stat:nRet = 0, nErrNo = 2, LastErr = 2, _S_IFDIR=4000, _S_IFREG=0

\\172.16.254.101\d$\Lilong\tapefile\
_access:nRet = 0, nErrNo = 2, LastErr = 2
_stat:nRet = -1, nErrNo = 2, LastErr = 2, _S_IFDIR=0, _S_IFREG=0

\\172.16.254.101\d$\Lilong\tapefile\123
_access:nRet = 0, nErrNo = 2, LastErr = 2
_stat:nRet = 0, nErrNo = 2, LastErr = 2, _S_IFDIR=0, _S_IFREG=8000

\\172.16.254.101\d$\Lilong\tapefile\123\
_access:nRet = 0, nErrNo = 2, LastErr = 2
_stat:nRet = -1, nErrNo = 2, LastErr = 267, _S_IFDIR=0, _S_IFREG=0

\\172.16.254.101\d$\Lilong\tapefile\456
_access:nRet = 0, nErrNo = 2, LastErr = 267
_stat:nRet = 0, nErrNo = 2, LastErr = 267, _S_IFDIR=4000, _S_IFREG=0

\\172.16.254.101\d$\Lilong\tapefile\456\
_access:nRet = 0, nErrNo = 2, LastErr = 267
_stat:nRet = -1, nErrNo = 2, LastErr = 2, _S_IFDIR=0, _S_IFREG=0

  为了更好的检测文件还是目录路径是否存在,我写了以下函数,能针对文件还是目录进行检测:

#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>

// 返回值:
// 0:成功,指定的文件或目录路径存在
// ENOENT(2):指定的文件或目录路径不存在
// EINVAL(22):参数非法
// ENODEV(19):指定的路径存在,但是类型与指定的类型不一致
// 其他:其他错误
int IsPathExist(const CString strPathName, BOOL bCheckFilePath = TRUE)
{
CString strPathTmp(strPathName);

strPathTmp.Replace(_T("/"), _T("\\"));
strPathTmp.TrimRight(_T("\\"));
if (1 == strPathTmp.GetLength()) // 驱动器盘符
{
strPathTmp += _T(":\\");
}
else if (2 == strPathTmp.GetLength() && strPathTmp.Right(1) == _T(":"))
{
strPathTmp += _T("\\");
}

struct _stat stPath = {0};
int nRet = _tstat(strPathTmp, &stPath);

do
{
if (0 != nRet)
{
nRet = errno;
break ;
}

BOOL IsFilePath = (_S_IFREG == (_S_IFREG & stPath.st_mode));
BOOL IsDirPath = (_S_IFDIR == (_S_IFDIR & stPath.st_mode));

if ((bCheckFilePath && !IsFilePath)
|| (!bCheckFilePath && !IsDirPath))
{
nRet = ENODEV;
}

} while (FALSE);

return nRet;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息