Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Locking behaviour is different via network shares

I have been trying to lock a file so that other cloned services cannot access the file. I then read the file, and then move the file when finished. The Move is allowed by using FileShare.Delete.

However in later testing, we found that this approach does not work if we are looking at a network share. I appreciate my approach may not have been the best, but my specific question is:

Why does the below demo work against the local file, but not against the network file?

The more specific you can be the better, as I've found very little information in my searches that indicates network shares behave differently to local disks.

string sourceFile = @"C:\TestFile.txt";
string localPath = @"C:\MyLocalFolder\TestFile.txt";
string networkPath = @"\\MyMachine\MyNetworkFolder\TestFile.txt";

File.WriteAllText(sourceFile, "Test data");

if (!File.Exists(localPath))
    File.Copy(sourceFile, localPath);

foreach (string path in new string[] { localPath, networkPath })
{
    using (FileStream fsLock = File.Open(path, FileMode.Open, FileAccess.ReadWrite, (FileShare.Read | FileShare.Delete)))
    {
        string target = path + ".out";
        File.Move(path, target); //This is the point of failure, when working with networkPath

        if (File.Exists(target))
            File.Delete(target);
    }

    if (!File.Exists(path))
        File.Copy(sourceFile, path);
}

EDIT: It's worth mentioning that if you wish to move the file from one network share, to another network share while the lock is in place, this works. The problem only seems to occur when moving a file within the same file share while it is locked.

like image 816
MattH Avatar asked Oct 25 '22 16:10

MattH


1 Answers

I believe System.IO.File.Open() maps to the Win32 API function CreateFile(). In Microsoft's documentation for this function [ http://msdn.microsoft.com/en-us/library/aa363858(v=vs.85).aspx ], it mentions the following:

Windows Server 2003 and Windows XP/2000: A sharing violation occurs if an attempt is made to open a file or directory for deletion on a remote computer when the value of the dwDesiredAccess parameter is the DELETE access flag (0x00010000) OR'ed with any other access flag, and the remote file or directory has not been opened with FILE_SHARE_DELETE. To avoid the sharing violation in this scenario, open the remote file or directory with the DELETE access right only, or call DeleteFile without first opening the file or directory for deletion.

According to this, you would have to pass DELETE as the FileAccess parameter to IO.File.Open(). Unfortunately, the DELETE enumeration was not included as an option.

This problem only pertains to Windows 2003 and earlier. I have tested your code on Windows 2008 R2 SP1, and it works fine. So it is possible that it would also work on Windows 2008 as well.

like image 119
Brain2000 Avatar answered Nov 15 '22 13:11

Brain2000