在Synology NAS的远程文件夹上工作时,我遇到c ++ WinAPI方法LockFile()和WriteFile()的异常行为。 网络设置:
RS812从DS1815 +挂载一个文件夹作为CIFS远程文件夹(请参见https://www.synology.com/en-global/knowledgebase/DSM/help/FileStation/mountremotevolume)。
当我从Windows客户端访问RS812上的该远程文件夹并锁定该文件夹中的文件时,我无法再从同一线程对其进行写入。我非常确定没有其他线程/进程正在访问文件。
有趣的事实:我只能使用WinAPI方法来复制它-尽管使用PowerShell脚本不能复制它。
这是c ++ googletest,在将“ tempPath”设置为该远程文件夹中的文件时可以观察到该问题
TEST( FileLockTest, RemoteFolderTest ) {
auto tempPath = "\\\\nas\\Data\\RemoteFolder\\subfolder\\example.txt";
if(boost::filesystem::exists(tempPath)) {
boost::filesystem::remove(tempPath);
}
FileLock::Entity ent = CreateFile(tempPath,
GENERIC_ALL,
0,
NULL,
CREATE_NEW,
FILE_ATTRIBUTE_NORMAL,
NULL );
ASSERT_EQ(0, GetLastError());
bool hasLock = LockFile( ent, 0, 0, MAXDWORD, MAXDWORD );
ASSERT_TRUE(hasLock);
ASSERT_EQ(0, GetLastError());
char DataBuffer[] = "some example data";
DWORD bytesToWrite = (DWORD)strlen(DataBuffer);
DWORD bytesWritten = 0;
bool success = WriteFile(
ent,
DataBuffer,
bytesToWrite,
&bytesWritten,
NULL);
ASSERT_EQ(0, GetLastError());
ASSERT_TRUE(success);
}
测试失败,因为在调用WriteFile()之后getLastError()返回代码33(ERROR_LOCK_VIOLATION)。还可以观察到没有任何内容写入文件。 将路径更改为NAS上常规文件夹的路径时,测试不会失败。
这是PowerShell脚本,允许您设置文件锁,然后将其写入该文件夹中。任何暗示为什么该脚本与我的c ++实现行为不同的提示也都欢迎!
$path = $args[0]
if([System.IO.File]::Exists($path)) {
[System.IO.File]::Delete($path)
}
$file = [System.IO.File]::Create($path)
$file.lock(0, [Int64].MaxValue)
$enc = [system.Text.Encoding]::UTF8
$text = "Some example text"
$data = $enc.GetBytes($text)
$file.Write($data, 0, $data.length)
$file.close()