Я испытываю странное поведение методов WinFI c ++ LockFile () и WriteFile () при работе с удаленной папкой NAS-устройства Synology.
Настройка сети:
RS812 монтирует одну папку из DS1815 + в качестве удаленной папки CIFS (см. https://www.synology.com/en-global/knowledgebase/DSM/help/FileStation/mountremotevolume ).
Когда я получаю доступ к этой удаленной папке на RS812 из клиента Windows и блокирую файл в этой папке, я больше не могу писать в нее из того же потока. Я очень уверен, что нет другого потока / процесса, обращающегося к файлу.
Интересный факт: я могу воспроизвести это, используя только методы 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);
}
Тест не пройден, потому что getLastError () возвращает код 33 (ERROR_LOCK_VIOLATION) после вызова WriteFile (). Также можно заметить, что в файл ничего не записано.
Тест не дает сбоя при изменении пути к обычной папке на NAS.
Это сценарий PowerShell, который позволяет установить блокировку файла, а затем записать его в эту папку. Любые подсказки, почему этот скрипт ведет себя не так, как моя реализация на С ++, также приветствуются!
$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()
Задача ещё не решена.
Других решений пока нет …