- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我注意到在 Vista 上写入文件、关闭文件并将其移动到目标位置随机失败。具体来说,MoveFileEx() 会无缘无故地返回 ERROR_ACCESS_DENIED
。至少在 Vista SP1(32 位)上会发生这种情况。在 XP SP3 上不会发生。
找到 this thread在互联网上关于完全相同的问题,没有真正的解决方案。到目前为止,错误似乎是由 Vista 的搜索索引器引起的,请参见下文。
给出的代码示例足以重现问题。我也把它粘贴在这里:
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
bool test() {
unsigned char buf[] = {
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99
};
HANDLE h;
DWORD nbytes;
LPCTSTR fn_tmp = "aaa";
LPCTSTR fn = "bbb";
h = CreateFile(fn_tmp, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_ALWAYS, 0, 0);
if (h == INVALID_HANDLE_VALUE) return 0;
if (!WriteFile(h, buf, sizeof buf, &nbytes, 0)) goto error;
if (!FlushFileBuffers(h)) goto error;
if (!CloseHandle(h)) goto error;
if (!MoveFileEx(fn_tmp, fn, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED | MOVEFILE_WRITE_THROUGH)) {
printf("error=%d\n", GetLastError());
return 0;
}
return 1;
error:
CloseHandle(h);
return 0;
}
int main(int argc, char** argv) {
unsigned int i;
for (i = 0;; ++i) {
printf("*%u\n", i);
if (!test()) return 1;
}
return 0;
}
使用 Visual Studio 将其构建为控制台应用程序。正确的行为是打印测试编号的无限循环。在 Vista SP1 上,程序在随机迭代次数后退出(通常在进行 100 次迭代之前)。
这不会发生在 Windows XP SP2 上。根本没有运行防病毒软件;并且没有其他奇怪的后台进程(机器几乎是普通操作系统安装 + Visual Studio)。
编辑:通过 Process Monitor 进一步挖掘(感谢@sixlettervariables),我看不出有什么特别糟糕的地方。每次测试迭代都会产生 176 次磁盘操作,其中大部分来自 SearchProtocolHost.exe(搜索索引器)。如果搜索索引服务停止,则不会发生任何错误,因此看起来它就是罪魁祸首。
在失败时(当应用程序获得 ERROR_ACCESS_DENIED
时),SearchProtocolHost.exe 有两个 CreateFile(s) 到目标文件 (bbb),以读/写/删除共享模式打开,所以应该没问题。其中一个打开之后是机会锁 (FSCTL_REQUEST_FILTER_OPLOCK
),也许这就是原因?
无论如何,我发现我可以通过在文件上设置 FILE_ATTRIBUTE_TEMPORARY
和 FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
标志来避免这个问题。看起来 FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
本身就足够了,但是将文件标记为临时文件还可以显着减少由搜索索引器引起的磁盘操作。
但这不是真正的解决方案。我的意思是,如果一个应用程序不能指望能够创建一个文件并重命名它,因为某些 Vista 的搜索索引器正在干扰它,这完全是疯了!它应该继续重试吗?对用户大吼大叫(这是非常不可取的)?做点别的?
最佳答案
我建议你使用 Process Monitor (编辑:以前称为 FileMon 的艺术家) 观察并查看到底是哪个应用程序在阻碍。它可以向您显示在您的计算机上进行的文件系统调用的完整踪迹。
(编辑:感谢@moocha 对应用程序的更改)
关于c++ - Vista 上的随机 MoveFileEx 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/153257/
重启机器后,我使用下面的命令删除一些文件: MoveFileEx(PChar(File_Address), Nil, MOVEFILE_DELAY_UNTIL_REBOOT); 如何取消执行此命令并防
我注意到在 Vista 上写入文件、关闭文件并将其移动到目标位置随机失败。具体来说,MoveFileEx() 会无缘无故地返回 ERROR_ACCESS_DENIED。至少在 Vista SP1(32
我正在使用 MoveFileEx 移动文件。根据用户输入的内容,文件移动的位置可能位于单独的硬盘驱动器上。在这种情况下,MoveFileEx 失败,GetLastError 报告错误 ID 17,即:
我有一个自动更新系统,可以在重新启动时替换我现有的程序文件。 (可以说,这是一个非常复杂的程序,包含许多驱动程序、服务和用户级模块。真的没有其他办法。相信我。) 函数 MoveFileEx 与 MOV
好的,我有一个名为的文件 ANIME~1.MKV~FNH47B97 ANIME~1.MKV 它是完整的文件名。它是由用户命名的。我想把第一个重命名为ANIME~1.JPG。从操作系统的角度来看,它们似
我是一名优秀的程序员,十分优秀!