Почему fopen не может открыть файл, который существует? - PullRequest
6 голосов
/ 14 января 2011

Я работаю в Windows XP, использую Visual Studio 6 (да, я знаю, что он старый), создаю / поддерживаю C ++ DLL.Я столкнулся с проблемой, что fopen не удалось открыть существующий файл, он всегда возвращает NULL.

Я пробовал:

  • Проверка errno и _doserrno путем установки обоих на ноль и последующей проверки их снова, оба остаются нулевыми, и, таким образом, GetLastError () не сообщает об ошибках.Я знаю, что fopen не требуется устанавливать errno, когда он сталкивается с ошибкой в ​​соответствии со стандартом C.
  • Жесткое кодирование пути к файлу, который не является относительным.
  • Попробовал на другой машине разработчиков, тот же результат.

Действительно странная вещь - это CreateFile работает, и файл может быть прочитан с ReadFile.Мы считаем, что это работает в сборке релиза, однако мы также наблюдаем очень странное поведение в других областях приложения, и мы не уверены, связано ли это с этим.

Код приведен ниже, я неувидеть что-нибудь странное, это выглядит вполне стандартным для меня.Исходный файл не менялся в течение полугода.

HRESULT CDataHandler::LoadFile( CStdString szFilePath )
{
    //Code
    FILE* pFile;
    if ( NULL == ( pFile = fopen( szFilePath.c_str(), "rb") ) )
    {
        return S_FALSE;
    }
    //More code
}

Ответы [ 5 ]

10 голосов
/ 14 января 2011

Ответ:

Я нашел причину, слишком много открытых дескрипторов файлов вызвано некоторыми недавними обновлениями приложения.Они не изменяют код, хотя эта ошибка присутствует некоторое время.Я перешел в функцию fopen к функции _getstream.Это пытается найти поток, который не используется, функция ищет таблицу из 512 потоков. Достаточно, конечно, все 512, где используется, и другие вызовы fopen, где происходит сбой.Я использовал инструмент handle от sysinternals, чтобы увидеть количество использованных ручек.

2 голосов
/ 14 января 2011

Ваша функция имеет тип возврата HRESULT (где 0 - это хорошо), но вы возвращаете логическое значение (где 0 - это плохо).Это не может быть правдой ...

1 голос
/ 14 января 2011

Если у вас есть разумная версия VC6, то у вас есть исходный код для CRT, и вы можете перейти к вызову fopen и вплоть до вызова CreateFile, который будет выполнять CRT. (Будьте готовы к тому, что это будет довольно долгий путь вниз!)

0 голосов
/ 23 апреля 2014

У вас уже есть 512 открытых файлов.

Мы можем хранить не более 512 открытых файлов в приложении VC. Я предлагаю закрыть ненужные файлы, используя fclose.

0 голосов
/ 14 января 2011

поставить точку останова на линии fopen, вызвать ее в отладчике, ввести « ERR, hr » в окне «Watch», выполнить строку и проверить в «Watch», в чем была проблема. Скорее всего, это права доступа.

...