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

来源:互联网 发布:论文相似性检测软件 编辑:程序博客网 时间:2024/06/05 18:09

  判断一个文件和目录是否存在,可以使用_access或者_stat函数,但是要注意两点:

  1. _access能检测给定路径是否存在,但是无法区分这个路径是文件路径还是目录路径。比如指定路径d:\123,如果D盘下存在文件名为123的文件或者目录名为123的目录,_access返回信息都是存在的,但是无法区分这个路径是文件路径还是目录路径。_stat函数则能正确区分文件还是目录。
  2. 路径末尾是否能带有反斜杠“\”对于检测的结果也是不一样的:
    末尾是否能有"\"盘符目录文件本地网络本地网络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=0d_access:nRet = -1, nErrNo = 2, LastErr = 2_stat:nRet = -1, nErrNo = 2, LastErr = 2, _S_IFDIR=0, _S_IFREG=0d:_access:nRet = 0, nErrNo = 2, LastErr = 2_stat:nRet = -1, nErrNo = 2, LastErr = 2, _S_IFDIR=0, _S_IFREG=0d:\_access:nRet = 0, nErrNo = 2, LastErr = 2_stat:nRet = 0, nErrNo = 2, LastErr = 0, _S_IFDIR=4000, _S_IFREG=0d:\\_access:nRet = 0, nErrNo = 2, LastErr = 0_stat:nRet = 0, nErrNo = 2, LastErr = 2, _S_IFDIR=4000, _S_IFREG=0d:\123_access:nRet = 0, nErrNo = 2, LastErr = 2_stat:nRet = 0, nErrNo = 2, LastErr = 2, _S_IFDIR=0, _S_IFREG=8000d:\123\_access:nRet = -1, nErrNo = 22, LastErr = 123_stat:nRet = -1, nErrNo = 2, LastErr = 267, _S_IFDIR=0, _S_IFREG=0d:\123\\_access:nRet = -1, nErrNo = 22, LastErr = 123_stat:nRet = -1, nErrNo = 2, LastErr = 267, _S_IFDIR=0, _S_IFREG=0d:\456_access:nRet = 0, nErrNo = 2, LastErr = 267_stat:nRet = 0, nErrNo = 2, LastErr = 267, _S_IFDIR=4000, _S_IFREG=0d:\456\_access:nRet = 0, nErrNo = 2, LastErr = 267_stat:nRet = -1, nErrNo = 2, LastErr = 2, _S_IFDIR=0, _S_IFREG=0d:\456\\_access:nRet = 0, nErrNo = 2, LastErr = 2_stat:nRet = -1, nErrNo = 2, LastErr = 2, _S_IFDIR=0, _S_IFREG=0t_access:nRet = -1, nErrNo = 2, LastErr = 2_stat:nRet = -1, nErrNo = 2, LastErr = 2, _S_IFDIR=0, _S_IFREG=0t:_access:nRet = 0, nErrNo = 2, LastErr = 2_stat:nRet = -1, nErrNo = 2, LastErr = 2, _S_IFDIR=0, _S_IFREG=0t:\_access:nRet = 0, nErrNo = 2, LastErr = 2_stat:nRet = 0, nErrNo = 2, LastErr = 2, _S_IFDIR=4000, _S_IFREG=0t:\123_access:nRet = 0, nErrNo = 2, LastErr = 2_stat:nRet = 0, nErrNo = 2, LastErr = 2, _S_IFDIR=0, _S_IFREG=8000t:\123\_access:nRet = 0, nErrNo = 2, LastErr = 2_stat:nRet = -1, nErrNo = 2, LastErr = 267, _S_IFDIR=0, _S_IFREG=0t:\456_access:nRet = 0, nErrNo = 2, LastErr = 267_stat:nRet = 0, nErrNo = 2, LastErr = 267, _S_IFDIR=4000, _S_IFREG=0t:\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;}


0 0
原创粉丝点击