سؤال

لقد كنت أحاول قفل ملف بحيث لا يمكن للخدمات المستنسخة الأخرى الوصول إلى الملف. ثم قرأت الملف ، ثم نقل الملف عند الانتهاء. هذه الخطوة مسموح بها باستخدام 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);
}

تحرير: تجدر الإشارة إلى أنه إذا كنت ترغب في نقل الملف من مشاركة شبكة واحدة ، إلى مشاركة شبكة أخرى أثناء وجود القفل ، فهذا يعمل. يبدو أن المشكلة تحدث فقط عند نقل ملف داخل نفس الشيء مشاركة الملف أثناء قفلها.

هل كانت مفيدة؟

المحلول

أعتقد أن System.io.file.open () خرائط إلى وظيفة API Win32 CreateFile (). في وثائق Microsoft لهذه الوظيفة [ http://msdn.microsoft.com/en-us/library/AA363858(V=VS.85).aspx ] ، يذكر ما يلي:

Windows Server 2003 و Windows XP/2000: يحدث انتهاك للمشاركة إذا تم إجراء محاولة لفتح ملف أو دليل للحذف على جهاز كمبيوتر بعيد عندما تكون قيمة معلمة DWDesiredAccess هي علامة الوصول الحذف (0x00010000) أو مع أي شيء لم يتم فتح علامة الوصول الأخرى ، والملف البعيد أو الدليل مع file_share_delete. لتجنب انتهاك المشاركة في هذا السيناريو ، افتح الملف أو الدليل عن بُعد مع Delete Access Right فقط ، أو استدعاء DeleteFile دون فتح الملف أو الدليل أولاً للحذف.

وفقًا لهذا ، يجب عليك تمرير الحذف كمعلمة fileAccess إلى io.file.open (). لسوء الحظ ، لم يتم تضمين تعداد الحذف كخيار.

هذه المشكلة تتعلق فقط بنظام التشغيل Windows 2003 وما قبله. لقد اختبرت الكود الخاص بك على Windows 2008 R2 SP1 ، وهو يعمل بشكل جيد. لذلك من الممكن أن تعمل أيضًا على Windows 2008 أيضًا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top