boost :: filesystem :: relative()无法访问该文件,因为它正在被另一个进程使用 [英] boost::filesystem::relative() cannot access the file because it is being used by another process

查看:160
本文介绍了boost :: filesystem :: relative()无法访问该文件,因为它正在被另一个进程使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

访问某些网络驱动器时,函数 relative(path,base_path) canonical(path,base_path)会引发异常.该消息始终为:

When accessing some network drives, the functions relative(path, base_path) and canonical(path, base_path) throw an exception. The message is always:

该进程无法访问该文件,因为该文件正在被另一个进程使用

The process cannot access the file because it is being used by another process

我仅在由我们IT部门操作并包含符号链接的某些共享网络驱动器上观察到了此行为.我无法在本地驱动器或相邻计算机的共享驱动器上引发相同的问题.我们怀疑网络驱动器上使用的存档/备份解决方案也是此处的驱动程序.到目前为止,已知的因素是这些:

I've observed this behavior only on some shared network drives that were operated by our IT department and contain symbolic links. I was not able to provoke the same issue on local drives or on shared drives from an adjacent computer. Our suspicion is that the archive/backup solution used on the network drives is also a driver here. The known factors are these so far:

  • 驱动器必须是网络共享(驱动器等)
  • 路径需要包含符号链接组件
  • 驱动器在备份/归档解决方案下运行

我的问题是:

  • 这是 boost :: filesystem 中的潜在错误吗?
  • 我错过了任何可能解决问题的 boost :: filesystem 技巧吗?
  • is this a potential bug in boost::filesystem?
  • are there any potential boost::filesystem tricks that I've missed that would solve the issue?

一种可能的解决方法是重新实现 relative()函数,使其仅使用路径操作而不访问文件系统.但我想避免重新实施.

One possible workaround would be to re-implement the relative() function to use only path manipulation and does not access the filesystem. But I'd like to avoid the re-implementation.

一个小的示例程序,如果测试路径存在问题,则可能会出现问题:

An small sample program that may exhibit the problem if the tested path has the issue:

#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的目录:

I had the same problem where the path only contains a directory using boost 1.65.1:

unexpected exception: boost::filesystem::weakly_canonical: The process cannot access the file because it is being used by another process; 

这也仅在路径包含符号链接时在网络驱动器上发生.

This also only happens on a network drive when the path contains a symbolic link.

似乎这是一个同步问题.显然,使用boost:filesystem不能并行访问相同的符号链接.我定义了一个自定义函数,该函数封装并同步对weakly_canonical的访问:

It seems that this is a synchronization problem. Obviously using boost:filesystem the same symbolic link can not be accessed in parallel. I defined a custom function that encapsulates and synchronizes the access to 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

After that change the problem did not occur anymore. There also is a note about the underlying system error code ERROR_SHARING_VIOLATION in the documentation of boost::filesystem::status. See https://www.boost.org/doc/libs/1_70_0/libs/filesystem/doc/reference.html

我认为根本原因在于推动力来源:boost \ libs \ filesystem \ src \ operations.cpp

I think that the root cause is in the boost sources: boost\libs\filesystem\src\operations.cpp

read_symlink函数包含

The function read_symlink contains

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/zh-cn/windows/desktop/api/fileapi/nf-fileapi-createfilew ).此参数可能应该是FILE_SHARE_READ.在最新的升幅1.70中,该值保持不变.

The third parameter (value 0) is the dwShareMode passed to CreateFileW (see https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-createfilew). This parameter possibly should be FILE_SHARE_READ. This is still left unchanged in the latest boost 1.70.

这篇关于boost :: filesystem :: relative()无法访问该文件,因为它正在被另一个进程使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆