真正应该关闭的文件共享违规

时间:2010-06-19 22:05:31

标签: c++ windows-xp

我有一个通过以下方式修改XML文件的应用程序:

(a)打开它,

(b)创建一个临时文件并将修改后的版本写入其中,

(c)关闭两个文件,

(d)用临时文件替换原始文件。

当我在运行Vista的笔记本电脑上测试时,一切正常。在运行带有闪存驱动器而不是硬盘(可能相关或不相关)的XP Professional SP2的嵌入式PC上,它在步骤(d)中因访问冲突而失败(错误代码5)。

如果我在步骤(c)和(d)之间插入代码以验证文件已关闭,则确认它们是;如果我在步骤(c)和(d)之间插入代码以尝试删除原始文件,则会因共享冲突而失败(代码32)。如果此时暂停程序并尝试从GUI中删除该文件,则会因共享冲突而失败。如果我此时使用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);

然后修改文件的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中?

非常感谢任何建议, 斯蒂芬。

2 个答案:

答案 0 :(得分:2)

使用Flash介质时要记住的一件事是访问时间可能会更长,而且文件操作经常是异步处理的。 Windows可能会返回到您的代码,说明文件在设备驱动程序实际释放之前已关闭。根据设备驱动程序,你去删除它,它仍然在使用中。

我建议在文件关闭之后和尝试删除文件之前在测试目的(例如5-10秒)中加一个延迟。如果它工作,那么你需要做的是循环删除操作几次(在循环中有一个短暂的延迟)并在删除成功时退出循环,或者你达到最大尝试次数(比如说4次) -5)。

如果你仍有同样的问题,即使有30秒的延迟,那么问题可能就在其他地方。

答案 1 :(得分:0)

这似乎是文件权限的问题。在尝试了其他各种不起作用的东西之后,我决定尝试打开具有读/写权限的文件(即使用“r +”属性而不是“r”),然后用内容覆盖原始文件内容。临时文件。这次,“_ wfopen_s”命令本身失败,错误代码为13(“权限被拒绝”),表明操作系统显然不愿意让程序在任何情况下都篡改该文件。

所以我想我需要稍微区别对待这个问题:为什么,何时

(a)我的应用程序在Vista中完美无缺,

(b)当我在XP中使用GUI时,我可以自由编辑文件,并且所有文件权限都可以正确设置,并且

(c)尝试修改文件的程序是从作为文件所有者“登录”的会话中运行的

...程序不能修改文件吗?

这是对XP的好奇心,还是它在带闪存的嵌入式计算机上运行的事实?如果是后者,我希望在创建全新的临时文件时也会出现问题,但这似乎工作正常。

我再次重视任何建议。

斯蒂芬