boost::filesystem::relative() 无法访问该文件,因为它正被另一个进程使用
boost::filesystem::relative() cannot access the file because it is being used by another process
访问某些网络驱动器时,函数relative(path, base_path)
和canonical(path, base_path)
抛出异常。消息总是:
The process cannot access the file because it is being used by another process
我仅在由我们的 IT 部门运营并包含符号 link 的某些共享网络驱动器上观察到此行为。我无法在本地驱动器或相邻计算机的共享驱动器上引发相同的问题。我们怀疑网络驱动器上使用的 archive/backup 解决方案也是此处的驱动程序。目前已知的因素是:
- 驱动器必须是网络共享(驱动器等)
- 路径需要包含符号link组件
- 驱动器在 backup/archive 解决方案下运行
我的问题是:
- 这是
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;
当路径包含符号 link.
时,这也只发生在网络驱动器上
看来这是一个同步问题。显然使用 boost:filesystem 不能并行访问相同的符号 link。
我定义了一个自定义函数,封装并同步访问 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\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。这在最新的boost 1.70中仍然保持不变。
我在多进程的情况下遇到了这个问题,所以@RED SOFT ADAIR 的锁解决方案没有帮助。在发布 Boost 修复程序之前,我实现了这个:
auto full_path = boost::filesystem::path(path_str).lexically_normal();
MY_ASSERT(boost::filesystem::exists(full_path), "Path normalization of '%s' resulted in non-existing path '%s'",
path_str.c_str(), full_path.string().c_str());
通过我创建的用于暴露此问题的测试,结果很好。 lexically_normal
对路径字符串进行操作,因此它不关心路径是否存在。但是当链接包含在路径中时,它很容易被误解。
截至八月/九月。 2020 年此问题也出现在 RStdio 1.2.5033 和 1.3.1073 - created an issue with RStudio dev on gihtub。
他们希望他们的下一个提升更新能够(再次)修复这个错误。
把它放在这里虽然它是一个 RStudio 主题 - 以防有人从 RStudio 方面遇到这个问题。
访问某些网络驱动器时,函数relative(path, base_path)
和canonical(path, base_path)
抛出异常。消息总是:
The process cannot access the file because it is being used by another process
我仅在由我们的 IT 部门运营并包含符号 link 的某些共享网络驱动器上观察到此行为。我无法在本地驱动器或相邻计算机的共享驱动器上引发相同的问题。我们怀疑网络驱动器上使用的 archive/backup 解决方案也是此处的驱动程序。目前已知的因素是:
- 驱动器必须是网络共享(驱动器等)
- 路径需要包含符号link组件
- 驱动器在 backup/archive 解决方案下运行
我的问题是:
- 这是
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;
当路径包含符号 link.
时,这也只发生在网络驱动器上看来这是一个同步问题。显然使用 boost:filesystem 不能并行访问相同的符号 link。 我定义了一个自定义函数,封装并同步访问 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\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。这在最新的boost 1.70中仍然保持不变。
我在多进程的情况下遇到了这个问题,所以@RED SOFT ADAIR 的锁解决方案没有帮助。在发布 Boost 修复程序之前,我实现了这个:
auto full_path = boost::filesystem::path(path_str).lexically_normal();
MY_ASSERT(boost::filesystem::exists(full_path), "Path normalization of '%s' resulted in non-existing path '%s'",
path_str.c_str(), full_path.string().c_str());
通过我创建的用于暴露此问题的测试,结果很好。 lexically_normal
对路径字符串进行操作,因此它不关心路径是否存在。但是当链接包含在路径中时,它很容易被误解。
截至八月/九月。 2020 年此问题也出现在 RStdio 1.2.5033 和 1.3.1073 - created an issue with RStudio dev on gihtub。
他们希望他们的下一个提升更新能够(再次)修复这个错误。
把它放在这里虽然它是一个 RStudio 主题 - 以防有人从 RStudio 方面遇到这个问题。