【问题标题】:How can we check if a file Exists or not using Win32 program?我们如何使用 Win32 程序检查文件是否存在?
【发布时间】:2011-04-19 05:37:46
【问题描述】:

我们如何使用 Win32 程序检查文件是否存在?我正在为 Windows Mobile 应用工作。

【问题讨论】:

  • std::filesystem::exists() C++17 以上

标签: windows winapi file


【解决方案1】:

您可以使用函数GetFileAttributes。如果文件不存在,则返回0xFFFFFFFF

【讨论】:

【解决方案2】:

您可以拨打FindFirstFile

这是我刚刚敲出的一个示例:

#include <windows.h>
#include <tchar.h>
#include <stdio.h>

int fileExists(TCHAR * file)
{
   WIN32_FIND_DATA FindFileData;
   HANDLE handle = FindFirstFile(file, &FindFileData) ;
   int found = handle != INVALID_HANDLE_VALUE;
   if(found) 
   {
       //FindClose(&handle); this will crash
       FindClose(handle);
   }
   return found;
}

void _tmain(int argc, TCHAR *argv[])
{
   if( argc != 2 )
   {
      _tprintf(TEXT("Usage: %s [target_file]\n"), argv[0]);
      return;
   }

   _tprintf (TEXT("Looking for file is %s\n"), argv[1]);

   if (fileExists(argv[1])) 
   {
      _tprintf (TEXT("File %s exists\n"), argv[1]);
   } 
   else 
   {
      _tprintf (TEXT("File %s doesn't exist\n"), argv[1]);
   }
}

【讨论】:

  • 纠正了一半。您需要检查 FILE_ATTRIBUTE_DIRECTORY。
  • 查看其他答案以获得更好的方法。此外,由于在 fileExists() 中使用了 argv[1],代码甚至无法按原样编译;
  • 糟糕的解决方案; GetFileAttributes() 好多了。
  • GetFileAttributes 是一个班轮
  • 假设file = "*",即使没有名为*的文件,这也可能返回true
【解决方案3】:

使用GetFileAttributes 检查文件系统对象是否存在并且它不是目录。

BOOL FileExists(LPCTSTR szPath)
{
  DWORD dwAttrib = GetFileAttributes(szPath);

  return (dwAttrib != INVALID_FILE_ATTRIBUTES && 
         !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
}

复制自How do you check if a directory exists on Windows in C?

【讨论】:

  • +1 因为一个简短的代码示例。代码示例可以节省入门时间。
  • 我想指出您的函数返回 bool 而不是 BOOL。
  • 对于 C++ 是的,对于 C,它是一个 BOOL
  • @Bitterblue:是的,这是我能找到的最快的。
  • 虽然GetFileAttributes()可能会因为文件不存在以外的错误条件返回INVALID_FILE_ATTRIBUTES
【解决方案4】:

您可以尝试打开文件。如果失败,说明大部分时间都不存在。

【讨论】:

  • 我会选择 CreateFile -> CloseHandle。最简单,最便宜。
  • 如果文件存在但用户没有足够的权限打开文件,文件打开也可能失败。这些天来,这是一个非常常见的情况。
  • 更不用说它不是最便宜的,因为文件可以在网络共享上,这会增加每次调用的延迟,而使用 CloseHandle,您有两个调用而不是一个。
【解决方案5】:

另一个选项:'PathFileExists'

但我可能会选择GetFileAttributes

【讨论】:

  • 另外PathFileExists需要使用“Shlwapi.dll”(在一些windows版本上不可用)并且比GetFileAttributes稍慢。
  • 但它不会告诉你文件或目录是否存在。
  • 顺便说一句,PathFileExists 只是 GetFileAttributes 的包装器,带有额外的 SetErrorMode(SEM_FAILCRITICALERRORS) 包装器。
【解决方案6】:

另一种更通用的非windows方式:

static bool FileExists(const char *path)
{
    FILE *fp;
    fpos_t fsize = 0;

    if ( !fopen_s(&fp, path, "r") )
    {
        fseek(fp, 0, SEEK_END);
        fgetpos(fp, &fsize);
        fclose(fp);
    }

    return fsize > 0;
}

【讨论】:

  • 如果你打算使用 fopen 等。你也可以使用_access(0)
  • @RobK 这具有跨平台的次要优势,而 _access 则不是。真正的问题是它会返回零长度文件不存在......
  • fopen_s 是 Microsoft 特定的,除了 0 字节文件被此损坏的代码声明为不存在之外,它还会在无法打开的文件(权限、共享)上失败。
【解决方案7】:

简单地说:

#include <io.h>
if(_access(path, 0) == 0)
    ...   // file exists

【讨论】:

  • Pierre 你是怎么找到这个功能的?有什么参考吗?
  • @Buddhika Chaturanga 早在 80 年代,我就开始在 Borland Turbo C 中使用它。这是在更高级的“CreateFile”之前检查文件是否存在的唯一方法。它隐藏在 Visual Studio 文档中。
【解决方案8】:

遇到了同样的问题,并在另一个使用GetFileAttributes 方法的forum 中找到了这个简短的代码

DWORD dwAttr = GetFileAttributes(szPath);
if (dwAttr == 0xffffffff){

  DWORD dwError = GetLastError();
  if (dwError == ERROR_FILE_NOT_FOUND)
  {
    // file not found
  }
  else if (dwError == ERROR_PATH_NOT_FOUND)
  {
    // path not found
  }
  else if (dwError == ERROR_ACCESS_DENIED)
  {
    // file or directory exists, but access is denied
  }
  else
  {
    // some other error has occured
  }

}else{

  if (dwAttr & FILE_ATTRIBUTE_DIRECTORY)
  {
    // this is a directory
  }
  else
  {
    // this is an ordinary file
  }
}

szPath 是文件路径。

【讨论】:

    【解决方案9】:

    使用OpenFileuStyle = OF_EXIST

    if (OpenFile(path, NULL, OF_EXIST) == HFILE_ERROR)
    {
        // file not found
    }
    // file exists, but is not open
    

    记住,使用OF_EXIST时,OpenFile成功后文件是打不开的。根据 Win32 文档:

    Value Meaning
    OF_EXIST (0x00004000) Opens a file and then closes it. Use this to test for the existence of a file.

    见文档: https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-openfile

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-07
      相关资源
      最近更新 更多