У меня есть приложение, которое изменяет файл XML с помощью:нарушения обмена на файл, который действительно должен быть закрыт
(а) его открытия,
(б) создание временного файла и запись модифицированной версии это,
(с) закрытие обоих файлов, и
(d) заменить исходный файл во временный файл.
Когда я тестирую его на своем ноутбуке под управлением Vista, все работает так, как должно. На встроенном ПК с XP Professional SP2 с флеш-накопителем вместо жесткого диска (что может быть или не быть релевантным), он не работает на этапе (d) с нарушением прав доступа (код ошибки 5).
Если я вставляю код между шагами (c) и (d), чтобы проверить, что файлы закрыты, он подтверждает, что они; если я поставил код между шагами (c) и (d), чтобы попытаться удалить исходный файл, он не работает с нарушением совместного доступа (код 32). Если я приостановил программу в этот момент и попытаюсь удалить файл из графического интерфейса пользователя, он не сможет выполнить нарушение доступа. Если я использую systinternals «Process Explorer» в этот момент, он показывает, что приложение все еще имеет дескриптор файла.
Вот некоторые из кода:
// Open the file which is to be updated:
_wfopen_s(&inStream, m_fileName, L"r, ccs=UTF-8");
// Obtain a suitable temporary filename from the operating system:
TCHAR lpTempPathBuffer[MAX_PATH]; // Buffer to hold temporary file path
TCHAR szTempFileName[MAX_PATH]; // Buffer to hold temporary file name
GetTempPath(MAX_PATH, lpTempPathBuffer);
GetTempFileName(lpTempPathBuffer,
TEXT("TMP"),
0,
szTempFileName);
// Now open a temporary file to hold the updates:
errno_t err = _wfopen_s(&outStream, szTempFileName, L"w, ccs=UTF-8");
if (err == 0)
printf ("Temporary file opened successfully\r\n");
else
printf ("Temporary file not opened; error code %d\r\n", err);
Тогда Габбинс что модифицирует файл, а затем ...
// Finally, we must close both files and copy the temporary file to
// overwrite the original input file:
int closerr = fclose(inStream);
if (closerr == 0)
printf("Original file closed properly\r\n");
else
printf("Original file not closed properly\r\n");
closerr = fclose(outStream);
if (closerr == 0)
printf("Temp file closed properly\r\n");
else
printf("Temp file not closed properly\r\n");
int numclosed = _fcloseall();
printf("Number of files closed = %d\r\n", numclosed);
// Should be zero, as we've already closed everything manually
if (!DeleteFile(m_fileName))
{
int err = GetLastError();
printf ("Delete file failed, error code was %d\r\n", err);
}
else
printf ("Delete file succeeded\r\n");
if (!MoveFileEx(szTempFileName, m_fileName,
MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED | MOVEFILE_WRITE_THROUGH))
{
int err = GetLastError();
printf ("Move file failed, error code was %d\r\n", err);
}
else
printf ("Move file succeeded\r\n");
Журнал вывода показывает:
«Временный файл успешно открыт
Оригинальный файл правильно закрыт
файл Temp закрыта
Количество файлов закрыто = 0
Удалить файл не удалось, код ошибки был 32
Переместить файл не удалось, код ошибки был 5"
Это не имеет никакого смысла ... Почему я получаю нарушение доступа к файлу, который настаивает операционная система, закрыт? И есть ли причина, почему это работает в Vista, но не в XP?
Огромное спасибо за советы, Stephen.
Вы уверены, что не существует какой-либо другой код, где-то, что открывает файл снова (или предотвращая его закрытия)? Вы должны запустить Process Monitor, чтобы убедиться, что все вызовы Open имеют соответствующие вызовы Close. – Luke
Нет, это определенно не проблема; это проблема с правами доступа к файлам (см. ниже). –