Як ми можемо перевірити, чи існує файл чи не за допомогою програми Win32?


74

Як ми можемо перевірити, чи існує файл чи не за допомогою програми Win32? Я працюю в додатку Windows Mobile.

Відповіді:


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.
Девід Хеффернан,

2
Див. Інші відповіді для кращих способів зробити це. Крім того, код навіть не компілюється як є через те, що argv [1] використовується у fileExists ();
Крістіан Айхінгер

3
Погане рішення; GetFileAttributes()набагато краще.
trojanfoe

2
GetFileAttributesє одним лайнером
Matt Clarkson

4
Припустимо file = "*", це може повернутися, trueнавіть якщо немає файлу з назвою *
Фелікс Домбек,

209

Використовуйте, GetFileAttributesщоб перевірити, чи існує об’єкт файлової системи та що це не каталог.

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

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

Скопійовано з Як перевірити, чи існує каталог у Windows на C?


5
+1 через короткий приклад коду. Приклади коду - це економія часу для початку роботи.
nalply

Я хотів би зазначити, що ваша функція повертає bool, а не BOOL.
Маріус Банчіла,

Для C ++ так, для C це BOOL
Zach Burlingame

Чи забезпечує це також найкращу ефективність при перевірці наявності файлів?
Bitterblue

1
@Bitterblue: Так, це так швидко, як мені вдалося знайти.
Cameron,

37

Ви можете скористатися цією функцією GetFileAttributes. Він повертається, 0xFFFFFFFFякщо файл не існує.


16
Цікава історія GetFileAttributes і чому це найкращий метод у коді Windows від Реймонда Чена: blogs.msdn.com/b/oldnewthing/archive/2007/10/23/5612082.aspx
Зак Берлінгейм

2
Вам потрібно перевірити, чи є об’єкт каталогом.
Девід Хеффернан,

8
Фактично він повертається, INVALID_FILE_ATTRIBUTESякщо файл не існує. На 64-бітній це може бути 0xFFFFFFFFFFFFFFFF.
Андреас Шпіндлер

7
@AndreasSpindler, оскільки тип повернення - це DWORDте, як він може повернутися 0xFFFFFFFFFFFFFFFF?
Аджай

Оновлене посилання на блог Реймонда Чена: devblogs.microsoft.com/oldnewthing/20071023-00/?p=24713
Рей

18

Як щодо просто:

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

П’єр Як ти знайшов цю функцію? будь-яке посилання?
Буддхіка Чатуранга,

2
@Buddhika Chaturanga Я почав використовувати його в Borland Turbo C ще в 80-х. Це був єдиний спосіб перевірити наявність файлу, до любителя "CreateFile". Це поховано в документації Visual Studio.
П'єр,

9

Інший варіант: 'PathFileExists' .

Але я б, мабуть, пішов GetFileAttributes.


2
Крім того, PathFileExistsпотрібно використовувати "Shlwapi.dll" (який недоступний у деяких версіях Windows) і трохи повільніший, ніж GetFileAttributes.
Bitterblue

Але це не говорить вам, чи існував файл чи каталог.
Джонатан Вуд,

До речі, PathFileExists - це просто обгортка для GetFileAttributes з додатковою обгорткою SetErrorMode (SEM_FAILCRITICALERRORS).
Олексій

0

Можна спробувати відкрити файл. Якщо це не вдалося, це означає, що не існує протягом більшості часу.


Я хотів би створити CreateFile -> CloseHandle. найпростіший і найдешевший.
OSH

4
Відкриття файлу також може не вдатися, якщо файли існують, але користувач не має достатніх привілеїв для відкриття файлу. У наші дні це дуже поширена ситуація.
JackLThornton

Не кажучи вже про те, що він не найдешевший, оскільки файл може бути на спільній мережі, що додає затримку для кожного дзвінка, і з 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).
Роб К

1
@RobK Це має незначну перевагу, оскільки є крос-платформним, тоді як _access - ні. Справжня проблема полягає в тому, що це призведе до того, що файли нульової довжини не існують ...
Перкінс

fopen_s є специфічним для Microsoft, і крім того, що 0-байтові файли визнані неіснуючими за допомогою цього непрацездатного коду, він також не працює у файлах, які він не може відкрити (дозволи, спільний доступ).
Ігор Левицький
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.