c++ - 确实应该关闭的文件共享违规

标签 c++ windows-xp

我有一个通过以下方式修改 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/

相关文章:

c++ - 为什么 std::ostream 和 char 之间的 operator<< 函数是非成员函数?

c++ - 获取对 unordered_map operator[] 返回值的引用

C++ - 进程以管理员身份运行时的 GetUserName()

command-line - Win XP 中命令行实用程序的代理

Powershell:以递归方式替换目录中选择子文件中的字符串

c++ - 2d(3d) 坐标的 HashMap (即 double vector )?

c++ - 使用 OpenCV 在实时视频帧中检测 LED 阵列中的每个 LED

mfc - 在 Windows XP 中单击项目复选框时,CTreeCtrl 'TVN_ITEMCHANGED ' 没有被触发?

batch-file - 如何在windows xp中使用批处理文件检查端口80是否可用

c++ - 模板和单独编译