2010-03-24 4 views
1

У меня есть приложение VC++, и в моем приложении у меня есть некоторые основные операции с файлами.Исключение при открытии файла

Ниже недобросовестный код

CStdioFile cFile; 
CFileException e; 
CString sReport; 
CString sHtmlfile = "testreport.html" 
OutputDebugString((sHtmlfile)); 
if (!cFile.Open(sHtmlfile,CFile::modeCreate | CFile::modeWrite, &e)) 
{ 
} 

Проблема заключается в мое приложение выполняет этот кусок кода каждые несколько минут. и он отлично работает.

После нескольких прогонов кода функция cFile.Open() выходит из строя. Я пытался получить сообщение об ошибке

TCHAR szError[1024]; 
e.GetErrorMessage(szError,1024); 
OutputDebugString((szError)); 

Ирония является сообщение об ошибке szError является «ошибка не произошла».

Это снова работает после перезапуска приложения. Любая идея, почему это происходит.

Заранее спасибо.

+0

Пожалуйста, открепите свой код, чтобы он был отформатирован. (просто отметьте его и нажмите кнопку кода). –

+2

Этот код напоминает мне, почему я ненавижу MFC. – sbi

+4

Мое первое предположение заключалось в том, что при определенных обстоятельствах файл не закрывается. Но поскольку вы уверены, что он закрыт, какие другие процессы используют файл? Веб-браузер? Может ли что-нибудь еще читать файл (и открыть его с помощью «shareDenyWrite» или аналогичного режима) в то время, когда вы пытаетесь его открыть? – Nate

ответ

2

У вас есть несколько экземпляров? Я предлагаю вам использовать Process Explorer, когда возникает ошибка, чтобы узнать, существуют ли какие-либо другие дескрипторы указанного файла.

И GetLastError сообщит об ошибке, о которой сообщает последняя функция API. Если между вызовом API отказа и вызовами GetLastError были какие-либо другие вызовы API, то последнее значение ошибки будет перезаписано. (Как уже указывал @sbi в комментариях.)

+0

Нет, у меня нет нескольких экземпляров. Позвольте мне посмотреть, могу ли я использовать проводник процессов. Да, правда, но я не звоню никому другому API, так что последнее значение ошибки не может быть перезаписано. Вы можете передать код выше. – ckv

+1

В классе 'CStdioFile :: Open' могут быть другие вызовы API. Источник для CStdioFile поставляется вместе с MFC ... может помочь посмотреть (хотя опыт говорит иначе). –

+0

Да, это все. – ckv

1

Maube вы забудете закрыть свой файл, и он выходит из дескрипторов файлов. Они закрыты, когда вы выходите из приложения, и вы можете запустить его снова. Проверьте, закрыты ли ваши файлы или нет.

OK. Если это не так, то что это может быть? Вы получаете сообщение об ошибке из cFile.Open, поэтому мы можем поверить, что это точно.

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

+0

CFile.Close вызывается в конце этой функции. Так что это не должно быть проблемой – ckv

+2

@viswanathan: Это верно, только если 'cFile.Close()' фактически выполняется. Если вам нужно сделать это вручную, есть хорошая вероятность, что исключение не позволит выполнить его. (Или ранний «возврат» за все, что мы знаем. Мы не видели ваш код.) Это для RAII. – sbi

+0

Ну, можно быть уверенным, что CFile.Close() фактически выполняется. До этого нет обратных заявлений.Я проверил это, выполнив код. – ckv

1

Вы используете C++. Ваша ошибка может быть полностью в другом месте. У меня была ошибка указателя, из-за которой чистый код кашлял ошибку.

Вы пытались построить в режиме выпуска?

Я предлагаю попытаться пройти и, возможно, сузить место, где появляется ваша ошибка.

+0

Я прошел через код, и я смог узнать, что он не прошел точно в CFile :: Open(). Когда я запускаю то же самое в сборке релизов, я также могу воспроизвести проблему с одинаковыми результатами. Что еще я должен попробовать? – ckv

+0

попробуйте добавить NULL в качестве третьего параметра для Open() и объединить вызов функции в разделе try/catch, улавливая исключение CFileException. Я предполагаю это из документов: «В то время как конструктор CFile генерирует исключение в состоянии ошибки, Open вернет FALSE для условий ошибки». Я также вижу, что вы, скорее всего, скопировали пример из открытых документов. На определенном различии заключается в том, что они используют char *, и вы используете CString. Вы уверены, что CString правильно переводит в LPCTSTR? – PLG

+0

Другое предложение, которое зависит от моего предыдущего сообщения ...чтобы проверить, не переписывается ли адресное пространство вашей CString в какой-то момент. Это будет признаком того, что ваша ошибка связана с диким указателем. – PLG

Смежные вопросы