我们如何使用Win32程序检查文件是否存在?


74

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

Answers:


27

您可以致电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]);
   }
}

4
纠正了一半。您需要检查FILE_ATTRIBUTE_DIRECTORY。
David Heffernan

2
请参阅其他答案,以获得执行此操作的更好方法。另外,由于在fileExists()中使用了argv [1],因此该代码甚至无法按原样编译;
Christian Aichinger

3
解决方案差;GetFileAttributes()好多了。
trojanfoe 2013年

2
GetFileAttributes是一个班轮
马特·克拉克森

4
假设file = "*"true即使没有名为*的文件,这也可能返回
Felix Dombek

209

使用GetFileAttributes检查文件系统对象存在,它不是一个目录。

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

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

复制自如何检查Windows中C中是否存在目录?


5
+1是一个简短的代码示例。代码示例可帮助您节省时间。
2012年

我想指出,您的函数返回的是bool而不是BOOL。
Marius Bancila 2012年

对于C ++是的,对于C,则是布尔值
Zach Burlingame 2012年

这还会在文件存在性检查中提供最佳性能吗?
Bitterblue

1
@Bitterblue:是的,这和我已经找到的一样快。
卡梅隆

37

您可以使用该功能GetFileAttributes0xFFFFFFFF如果文件不存在,则返回。


16
关于GetFileAttributes的有趣历史以及为什么它是Raymond Chen首选的Windows代码方法:blogs.msdn.com/b/oldnewthing/archive/2007/10/23/5612082.aspx
Zach Burlingame

2
您需要检查对象是否为目录。
David Heffernan

8
实际上,INVALID_FILE_ATTRIBUTES如果文件不存在,它将返回。在64位上可能是0xFFFFFFFFFFFFFFFF
Andreas Spindler

7
@AndreasSpindler,既然返回类型是DWORD如何返回的0xFFFFFFFFFFFFFFFF
阿贾伊

更新到雷蒙德·陈(Raymond Chen)博客的链接:devblogs.microsoft.com/oldnewthing/20071023-00/?p=24713

18

简单地说:

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

皮埃尔(Pierre)您是如何找到此功能的?有参考吗?
佛祖卡·查图兰加'18

2
@Buddhika Chaturanga我早在80年代就开始在Borland Turbo C中使用它。在发烧友“ CreateFile”之前,这是检查文件是否存在的唯一方法。它埋在Visual Studio文档中。
皮埃尔

9

另一个选项: “ PathFileExists”

但我可能会同意GetFileAttributes


2
此外,还PathFileExists需要使用“ Shlwapi.dll”(在某些Windows版本中不可用),并且比慢一些GetFileAttributes
Bitterblue 2013年

但是它不会告诉您是否存在文件或目录。
乔纳森·伍德

顺便说一句,PathFileExists只是带有附加SetErrorMode(SEM_FAILCRITICALERRORS)包装器的GetFileAttributes包装器。
亚历克斯(Alex)

0

您可以尝试打开文件。如果失败,则表示大多数时间不存在。


我会选择CreateFile-> CloseHandle。最简单,最便宜。
OSH 2013年

4
如果文件存在但用户没有足够的权限打开文件,则文件打开也会失败。这些天,这是非常普遍的情况。
JackLThornton '16

更不用说它不是最便宜的,因为该文件可以在网络共享上,这会增加每个呼叫的延迟,而使用CloseHandle,您有两个而不是一个。
伊戈尔·莱维奇

-2

另一种更通用的非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)
罗伯K

1
@RobK具有跨平台的次要优势,而_access则不是。真正的问题是它将返回零长度文件不存在……
Perkins

fopen_s是Microsoft特定的,除了此损坏的代码声明0字节文件不存在外,fopen_s在无法打开的文件(权限,共享)上也会失败。
伊戈尔·莱维奇
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.