Почему fopen не может открыть существующий файл?
Вопрос
Я нахожусь в 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
}
Нет правильного решения
Другие советы
Ответ:
Я нашел причину, слишком много дескрипторов открытых файлов вызвано некоторыми недавними обновлениями приложения.Однако там код не меняется, так что эта ошибка присутствует уже некоторое время.Я перешел в функцию fopen вплоть до функции под названием _getstream .Это попытка найти неиспользуемый поток, функция выполняет поиск в таблице из 512 потоков, достаточно уверенная во всех 512, где используется, и в других вызовах fopen, где происходит сбой.Я использовал ручка инструмент из sysinternals для просмотра количества используемых дескрипторов.
Ваша функция имеет возвращаемый тип HRESULT (где 0 - это хорошо), но вы возвращаете логическое значение (где 0 - это плохо).Этого не может быть...
Предполагая, что у вас есть приемлемая версия VC6, тогда у вас есть исходный код CRT, и вы можете перейти к вызову fopen и вплоть до вызова CreateFile, который выполнит CRT.(Будьте готовы к тому, что это будет довольно долгий путь вниз!)
поставьте точку останова в строке fopen, запустите ее в отладчике, введите "ОШИБКА, hr" в окне "Смотреть" выполните строку и проверьте в Watch, в чем была проблема.Скорее всего, это права доступа.
У вас уже есть 512 открытых файлов.
Мы можем хранить не более 512 открытых файлов в приложении VC.Я предлагаю закрыть ненужные файлы с помощью fclose
.