Какой лучший способ проверить, существует ли файл в C?

394
задан jww 22 February 2019 в 00:48
поделиться

5 ответов

Ищите эти access() функция, найденная в unistd.h. Можно заменить функцию [1 112]

if( access( fname, F_OK ) != -1 ) {
    // file exists
} else {
    // file doesn't exist
}

, можно также использовать R_OK, W_OK, и X_OK вместо F_OK, чтобы проверить на разрешение чтения, записать разрешение и выполнить разрешение (соответственно), а не существование, и Вы можете ИЛИ любой из них вместе (т.е. проверьте и на чтение и на разрешение записи с помощью R_OK|W_OK)

Обновление : Обратите внимание, что в Windows, Вы не можете использовать W_OK для надежного тестирования на разрешение записи, так как функция доступа не принимает DACLs во внимание. access( fname, W_OK ) может возвратиться 0 (успех), потому что файлу не установили атрибут "только для чтения", но у Вас все еще не может быть разрешения записать в файл.

534
ответ дан gsamaras 22 February 2019 в 10:48
поделиться

Да. Используйте stat(). См. страницу справочника для stat(2) .

stat() перестанет работать, если файл не будет существовать, иначе скорее всего, успешно выполняться. Если это действительно будет существовать, но у Вас нет доступа для чтения к каталогу, где это существует, то это также перестанет работать, но в этом случае какой-либо метод перестанет работать (как можно осмотреть содержание каталога, который Вы не можете видеть согласно правам доступа? Просто, Вы не можете).

, О, поскольку кто-то еще упомянул, можно также использовать access(). Однако я предпочитаю stat(), как будто файл существует, это сразу получит меня большая полезная информация (когда было это последнее обновление, насколько большой это, владелец и/или группа, которая владеет файлом, правами доступа, и так далее).

30
ответ дан a stone arachnid 22 February 2019 в 10:48
поделиться

Используйте статистику как это:

bool file_exist (char *filename)
{
  struct stat   buffer;   
  return (stat (filename, &buffer) == 0);
}

и вызов это как это:

if (file_exist ("myfile.txt"))
{
  printf ("It exists\n");
}
109
ответ дан Soleil 22 February 2019 в 10:48
поделиться
  • 1
    Я думаю, что будет лучше поместить его что дублирующаяся ссылка на комментарий под самим вопросом. Прямо сейчас это предполагает, что Ваш ответ является дубликатом. – Bhesh Gurung 15 December 2011 в 15:52

От справки Visual C++ я был бы склонен идти с [1 110]

/* ACCESS.C: This example uses _access to check the
 * file named "ACCESS.C" to see if it exists and if
 * writing is allowed.
 */

#include  <io.h>
#include  <stdio.h>
#include  <stdlib.h>

void main( void )
{
   /* Check for existence */
   if( (_access( "ACCESS.C", 0 )) != -1 )
   {
      printf( "File ACCESS.C exists\n" );
      /* Check for write permission */
      if( (_access( "ACCESS.C", 2 )) != -1 )
         printf( "File ACCESS.C has write permission\n" );
   }
}

Также стоящий замечания значения режима _access(const char *path, int mode ):

  • 00: Существование только [1 112]

  • 02: Запишите разрешение

  • 04: разрешение

  • 06 Чтения: Прочитайте и запишите разрешение

, Поскольку Ваш fopen мог перестать работать в ситуациях, где файл существовал, но не мог быть открыт согласно просьбе.

Редактирование: Просто читайте сообщение Mecki. stat() действительно похож на более опрятный способ пойти. Гул Ho.

6
ответ дан a stone arachnid 22 February 2019 в 10:48
поделиться

Обычно, когда Вы хотите проверить, существует ли файл, это - потому что Вы хотите к , создают , что файл, если это не делает. Ответ Graeme Perrow хорош, если Вы не делаете , хотят создать тот файл, но это уязвимо для состояния состязания, если Вы делаете: другой процесс мог создать файл, промежуточный Вы проверяющий, существует ли он, и Вы на самом деле открытие его для записи в него. (Не смейтесь..., это могло иметь плохой последствия безопасности, если бы созданный файл был символьной ссылкой!)

, Если Вы хотите проверить на существование и , создают файл, если это не существует, атомарно так, чтобы не было никаких условий состязания, затем используйте это:

#include <fcntl.h>
#include <errno.h>

fd = open(pathname, O_CREAT | O_WRONLY | O_EXCL, S_IRUSR | S_IWUSR);
if (fd < 0) {
  /* failure */
  if (errno == EEXIST) {
    /* the file already existed */
    ...
  }
} else {
  /* now you can use the file */
}
77
ответ дан Dan Lenski 22 February 2019 в 10:48
поделиться
  • 1
    Это работало. Я не мог найти никакое другое практическое решение под Ubuntu/Debian. – Marquez 22 January 2013 в 09:56
Другие вопросы по тегам:

Похожие вопросы: