Проблема с открытием файла, после удаления файла. Fopen статус не работает в VC ++

0

пример fopen

#include <stdio.h>

int _tmain(int argc, _TCHAR* argv[])
{
    FILE * pFile;
    for(int i=0; i < 1000000; i++)
    {
        bool ret = remove("C:\\abc.txt");
        pFile = fopen ("C:\\abc.txt","w");
        if (pFile!=NULL)
        {
            fputs ("fopen example",pFile);
            fclose (pFile);
        }
        else
        {
            printf("%d fopen() fails \n", count);
        }
    }
    return 0;
}

Здесь, после вызова remove, pFile = fopen ("C:\abc.txt", "w"), вызывается,

Иногда даже в C:\файл abc.txt отсутствует после вызова remove, но указатель fopen pFile имеет значение NULL.

Это воспроизводится несколько раз не всегда. В этом примере эта проблема воспроизводится 50/60 раз.

Пожалуйста, предложите некоторое решение.

  • 3
    Вы пытались проверить переменную errno? Система может установить некоторый код ошибки, который может помочь вам в этой проблеме, вы можете использовать perror для сбора дополнительной информации. Также посмотрите на pubs.opengroup.org/onlinepubs/009695399/functions/fopen.html
  • 0
    Похоже на состояние гонки. Возможные оптимизации в базовой файловой системе могут позволить remove return до того, как все действительно будет очищено, и немедленно создать файл с такими же разрывами имен. Попробуйте добавить короткий сон между удалением и созданием: это должно работать.
Показать ещё 4 комментария
Теги:
visual-c++

2 ответа

1

Если вы уже установили, что это проблема состояния гонки в базовой файловой системе, правильный способ ее исправить (как было предложено BLUEPIXY), просто remove вызов remove:

pFile = fopen ("C:\\abc.txt","w");

создаст файл, если он не существует и усекает его до размера 0, если он существует, что именно вам нужно.

  • 0
    Я использую функцию-обертку, в которой дается вызов fopen. В этом случае, если файл будет удален, он будет открыт в режиме записи, иначе в режиме rb +. Таким образом, в случае, когда он должен быть удален и снова создан, проблема возникает. Также я проверил возвращаемое значение функции remove (), чтобы подтвердить, что удаление было успешным, к моему удивлению, я обнаружил, что иногда remove возвращает успешное значение, и дальнейшее fopen завершается с ошибкой, выдавая «Permission denied» как error, а иногда и remove () происходит сбой, но Fopen успешно. remove () представляется ненадежной функцией.
  • 0
    @Aakash: remove не является самой ненадежной функцией. Но в Windows происходит сбой при вызове открытого файла (кроме специального режима доступа), поэтому у вас возникает та же проблема гонки. ИМХО, вам следует пересмотреть свой алгоритм, чтобы не делать вызов удаления. В ваших условиях использования это небезопасно.
Показать ещё 1 комментарий
0

Если вам необходимо создать файл после удаления файла, вы можете задержать fopen, пока не убедитесь, что старый файл "abc.txt" удален.

Для этого вам нужно ввести некоторый цикл, чтобы подтвердить его, как показано ниже,

bool ret = remove("C:\\abc.txt");
FILE * rFile;
while(true)
{
    rFile = fopen ("C:\\abc.txt","r");
    if(rfile == null)
       break; //File Removed confirmed!!
    else
       sleep(100); //Loop around again...
}
pFile = fopen ("C:\\abc.txt","w");
if (pFile!=NULL)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню