我不得不注意到 Bazaar 的一些奇怪行为我的机器上的目录锁定机制并尝试重现该机制。这是我的简单测试用例:
创建目录
Test
,然后创建Test/held
,然后创建文件Test/held/info
。将
Test
重命名为YXCV
。读取第 1 步中创建的文件(现在从路径
YXCV/held/info
)。清理(删除文件和目录)。
重复。
奇怪的是,这失败了。有时在步骤 2 中(“权限被拒绝”),有时在步骤 3 中(无法打开文件,尽管之后我可以在常规文本编辑器中打开该文件)。 有时会立即失败,有时会成功执行数千次迭代。
我这里运行的是 Windows 7。我怀疑某些配置发生了变化(公司 IT 管理超出了我的控制范围),因为问题发生在一周前。
你知道任何可能的合理解释吗?
这是我的测试代码:
#include <iostream>
#include <fstream>
#include <direct.h>
#include <stdio.h>
void mkdir() {
if ( mkdir( "Test" ) ) throw std::runtime_error( "mkdir" );
if ( mkdir( "Test/held" ) ) throw std::runtime_error( "mkdir" );
}
void create() {
if ( !std::ofstream( "Test/held/info" ).write( "asdf", 4 ) )
throw std::runtime_error( "create" );
}
void rename() {
if ( rename( "Test", "YXCV" ) ) throw std::runtime_error( "rename" );
}
void peek() {
char buf[ 4 ];
if ( !std::ifstream( "YXCV/held/info" ).read( buf, 4 ) )
throw std::runtime_error( "peek" );
}
void del() {
if ( unlink( "YXCV/held/info" ) ) throw std::runtime_error( "remove" );
if ( rmdir( "YXCV/held" ) ) throw std::runtime_error( "remove" );
if ( rmdir( "YXCV" ) ) throw std::runtime_error( "remove" );
}
void cleanup() {
unlink( "Test/held/info" );
rmdir( "Test/held" );
rmdir( "Test" );
unlink( "YXCV/held/info" );
rmdir( "YXCV/held" );
rmdir( "YXCV" );
}
int main() {
cleanup();
int count = 1;
try {
for ( ;; ++count ) {
mkdir ();
create();
rename();
peek ();
del ();
}
}
catch ( const std::exception &e ) {
std::cout << "Run: " << count << "\nError: " << e.what() << "\n\t"
<< strerror( errno ) << '\n';
}
std::cin.get();
}
最佳答案
当我单独运行你的程序时,它会永远循环而不会出现错误。
但是,一旦我使用其他程序同时执行一些文件系统操作,您的代码就会完全按照您所描述的那样失败:
- 如果打开资源管理器窗口并在创建的叶目录中导航并留在那里,您的代码将无法删除或重命名目录(步骤 1 或 4)。
- 如果我使用某些文本编辑器打开新文件,则文件读取失败(步骤 3)。
这是 Windows 文件系统上的正常行为。例如,如果程序在目录上有句柄,则无法删除该句柄(rmdir()
错误代码 EACCESS
)。
您已经解释过您正在 Bazaar 版本管理目录结构中工作。这意味着一些后台服务进程会监视目录和文件的变化,并最终执行一些hooks and plugins (这可能会延长锁定条件)。这通常会产生上述锁定情况。
P.S:为了帮助您了解发生了什么,您可以使用 Microsoft 的 process explorer并使用 Ctrl+F 搜索文件句柄。在“句柄”字段中输入文件名,它将显示哪些进程使用该文件。注意:需要以管理员身份运行才能搜索系统进程。
关于c++ - Windows 上不可靠的文件系统操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33637513/