访问某些网络驱动器时,函数relative(path, base_path)
和canonical(path, base_path)
会抛出异常。消息总是:
该进程无法访问该文件,因为该文件正由另一个进程使用
我只在一些由我们的IT部门运营并包含符号链接的共享网络驱动器上观察到此行为。我无法在本地驱动器或相邻计算机的共享驱动器上引发相同的问题。我们怀疑网络驱动器上使用的存档/备份解决方案也是此处的驱动程序。到目前为止,已知因素是:
我的问题是:
boost::filesystem
的潜在错误吗?boost::filesystem
技巧,我错过了将解决问题?一种可能的解决方法是重新实现relative()
函数以仅使用路径操作而不访问文件系统。但我想避免重新实施。
如果测试路径存在问题,可能会出现问题的小示例程序:
#include <vector>
#include <string>
#include <tuple>
#include <boost/filesystem.hpp>
#include <boost/system/error_code.hpp>
using namespace std;
using namespace boost::filesystem;
using boost::system::error_code;
int main()
{
vector<string> testpaths = {
"< path to a directory which is to test >",
};
for(auto & line : testpaths)
{
if(line.empty()) continue; // skip empty lines
cout << " path: " << line << " ";
path testpath(line.c_str());
// simplified testing, use parent of parent
path basepath = testpath.parent_path().parent_path();
boost::system::error_code ec;
path relpath = relative(testpath, basepath, ec);
if(ec) cout << " ---> error: " << ec.message();
else cout << " ok, relative: " << relpath.string();
cout << endl;
}
}
我有同样的问题,其中路径只包含使用boost 1.65.1的目录:
unexpected exception: boost::filesystem::weakly_canonical: The process cannot access the file because it is being used by another process;
当路径包含符号链接时,这也仅发生在网络驱动器上。
这似乎是一个同步问题。显然使用boost:filesystem不能并行访问相同的符号链接。我定义了一个自定义函数,它封装并同步对weakly_canonical的访问:
static boost::recursive_mutex sgCanonicalMutex;
boost::filesystem::path CanonicalPath(const boost::filesystem::path inPath)
{
boost::recursive_mutex::scoped_lock lk(sgCanonicalMutex);
return boost::filesystem::weakly_canonical(inPath);
}
在那之后,问题不再发生了。还有一个关于boost :: filesystem :: status文档中的底层系统错误代码ERROR_SHARING_VIOLATION的注释。见https://www.boost.org/doc/libs/1_70_0/libs/filesystem/doc/reference.html
我认为根本原因在于boost源:boost \ libs \ filesystem \ src \ operations.cpp
函数read_symlink包含
handle_wrapper h(
create_file_handle(p.c_str(), GENERIC_READ, 0, 0, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, 0));
第三个参数(值0)是传递给CreateFileW的dwShareMode(请参阅https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-createfilew)。此参数可能应为FILE_SHARE_READ。在最新的1.70提升中,这仍然保持不变。