网络共享的锁定行为有所不同

发布于 2024-08-30 11:44:15 字数 1115 浏览 6 评论 0原文

我一直在尝试锁定文件,以便其他克隆服务无法访问该文件。然后我读取该文件,完成后移动该文件。使用FileShare.Delete 允许移动。

然而,在后来的测试中,我们发现如果我们正在查看网络共享,则这种方法不起作用。我知道我的方法可能不是最好的,但我的具体问题是:

为什么下面的演示适用于本地文件,但不适用于网络文件?

越具体越好,因为我在搜索中发现很少的信息表明网络共享的行为与本地磁盘不同。

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);
}

编辑:值得一提的是,如果您希望在锁定到位时将文件从一个网络共享移动到另一个网络共享,那么这是可行的。该问题似乎仅在锁定时在同一文件共享内移动文件时才会出现。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

∞梦里开花 2024-09-06 11:44:15

我相信 System.IO.File.Open() 映射到 Win32 API 函数 CreateFile()。在 Microsoft 的此功能文档中 [ http://msdn .microsoft.com/en-us/library/aa363858(v=vs.85).aspx],它提到了以下内容:

Windows Server 2003 和 Windows XP/2000:当 dwDesiredAccess 参数的值为 DELETE 访问标志 (0x00010000) 或'时,如果尝试打开远程计算机上的文件或目录进行删除,则会发生共享冲突已使用任何其他访问标志进行编辑,并且远程文件或目录尚未使用 FILE_SHARE_DELETE 打开。为了避免这种情况下的共享冲突,请仅使用 DELETE 访问权限打开远程文件或目录,或者在不先打开要删除的文件或目录的情况下调用 DeleteFile。

据此,您必须将 DELETE 作为 FileAccess 参数传递给 IO.File.Open()。不幸的是,DELETE 枚举没有作为选项包含在内。

此问题仅与 Windows 2003 及更早版本有关。我已经在 Windows 2008 R2 SP1 上测试了您的代码,并且运行良好。因此它也可能在 Windows 2008 上运行。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文