我有一个通过以下方式修改 XML 文件的应用程序:
(a) 打开它,
(b) 创建一个临时文件并写入修改后的版本,
(c) 关闭两个文件,并且
(d) 用临时文件替换原来的文件。
当我在运行 Vista 的笔记本电脑上对其进行测试时,一切正常。在运行 XP Professional SP2 且带有闪存驱动器而不是硬盘(可能相关也可能不相关)的嵌入式 PC 上,它在步骤 (d) 失败并出现访问冲突(错误代码 5)。
如果我在步骤 (c) 和 (d) 之间插入代码以验证文件是否已关闭,它会确认它们已关闭;如果我在步骤 (c) 和 (d) 之间输入代码以尝试删除原始文件,它将因共享冲突而失败(代码 32)。如果我此时暂停程序并尝试从 GUI 中删除文件,它将因共享冲突而失败。如果此时我使用 sysinternals“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);
然后是修改文件的gubbins,然后...
// 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");
输出日志显示:
"临时文件打开成功
原文件正确关闭
正确关闭临时文件
关闭的文件数 = 0
删除文件失败,错误代码为32
移动文件失败,错误代码为 5"
这毫无意义...为什么我在操作系统坚持关闭的文件上遇到共享冲突?这是否适用于 Vista 但不适用于 XP?
非常感谢您的任何建议, 斯蒂芬。
最佳答案
对于 Flash 媒体要记住的一件事是访问时间可能会更长,并且文件操作经常是异步处理的。 Windows 可能会返回您的代码,说明文件在设备驱动程序实际释放之前已关闭。你去删除它,根据设备驱动程序,它真的还在使用。
出于测试目的,我建议在文件关闭之后和尝试删除文件之前,将延迟放在那里(比如 5-10 秒)。如果它有效,那么你需要做的是在删除操作上循环几次(循环中有一个短暂的延迟)并在删除成功时退出循环,或者你达到最大尝试次数(比如 4 -5).
如果您仍然遇到同样的问题,即使延迟了 30 秒,那么问题可能出在其他地方。
关于c++ - 确实应该关闭的文件共享违规,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3077407/