سؤال

معرفتي

أحتاج إلى كتابة أداة باستخدام .NET الإصدار 2.0 بأعلى (استخدام شيء خارج الرف ليس خيارا لهذا العميل لأسباب سياسية وتجارية وسرية / سرية / ثقة) لترحيل الملفات من خادم واحد إلى آخر عبر الشبكة. الخوادم هي خوادم الملفات للفرق المحلية، ويحتاج معينة مجلدات الفريق إلى أن يتم ترحيلها إلى خوادم أخرى لتسهيل إعادة التنظيم. الفكرة الأساسية هي قراءة كل ملف وتدفقها عبر الشبكة خارج ساعات وبعد بضعة أيام سيتم ترحيل البيانات. أذونات الملفات تحتاج إلى الحفاظ عليها. نظرا لأن هذا سيستغرق بضعة أيام (نحن نتحدث إلى عدة غيغابايت من البيانات، لبعض الفرق)، نحتاج إلى التكرار فوق الملفات كل ليلة ومقارنة تواريخ التعديل وتحديث تلك التي تغيرت. النظرية هي أنه في نهاية المطاف سيكون لدى الخادم الجديد نسخة محدثة من الملفات ويمكن للمستخدمين التبديل إلى الخادم الجديد. هذا هو بالطبع ليس بهذه البساطة، ولكن لدينا تصميم نعتقد أنه يجب أن تعمل :)

المشكلة

لذلك من الناحية النظرية، نقوم بفتح الملف، وتدفقها عبر الشبكة، واكتبها في الطرف الآخر، أليس كذلك؟ :)

لسوء الحظ، على الخوادم نفسها، تم إنشاء أسهم الملفات في مسارات المجلدات مثل:

D: البيانات أسهم الفريق Division Department Name of Team - يمكن أن يكون طويلا إلى حد ما

لكل مستخدم، يتم تعيين هذا المسار إلى محرك أقراص، على سبيل المثال، وسيتم تقاسمها باسم Server Teamname ومطبقة إلى T: Drive.

تسبب هذا في الموقف الذي تكون فيه الملفات المرئية من T: Drive داخل MAX_PATH الحد، ولكن عند عرضها محليا على الخادم نفسه، فإنها تتجه نحو ذلك. لا يمكننا الوصول إلى الملفات باستخدام مشاركات الشبكة لأن هذه الأداة تحتاج إلى أن تكون عامة، لتشغيل مئات هذه الخوادم، وليس هناك طريقة قياسية لمعرفة أسهم الملفات التي يجب أن نتحرك وتلك التي لا - هناك - هناك - هناك - هناك لا معيار اتفاقية التسمية حتى. أيضا، في بعض الأحيان هناك أسهم فرعية من الأسهم الأخرى، وبالتالي فإننا نتجاوز MAX_PATH الحد مرتين!

أنا أدرك الحل البديل لتحديد المسارات باستخدام بادئة "؟ "، والتي تعامل المسار كمسار UNC ويسمح بحد أقصى قدر كبير من الأحرف 32K.

يتم تنفيذ هذا الحل البديل على مستوى API Win32، ويعد مساحة الاسم System.io (في الغالب) بشكل أساسي مجرد غلاف رفيع حول وظائف API Win32 الأصليين، إلا أن Microsoft "مساعدة" صحة إضافية (غير صحيحة) قبل تسليم المكالمة إلى API وبعد في هذه الحالة، يرفض .NET Framework المسار لأنه يدعي أنه "؟" هو حرف مسار غير صالح.

لذا فإن سؤالي هو ... هل هناك طريقة لم أفكر في ذلك، سيتيح لي أن أعمل حول هذا دون الحاجة إلى إعادة كتابة مساحة الاسم بالكامل تقريبا، مما يجعل حمولة من مكالمات P / Invoke، فقط إزالة هذا التحقق المزعج؟

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

المحلول

قام فريق BCL بمسلسل 3 أجزاء حول سبب إجراء هذه الخيارات وما هي العمل المحرز. إذا لم تقرأ ذلك حتى الآن أقترح عليك القيام بذلك لأنه مصدر كبير للمعلومات حول هذا الموضوع

نصائح أخرى

ركضت في حل الطرف الثالث الذي قد يساعد: Alphafs..

يجب أن يكون من السهل إلى حد ما العمل حول هذا القيد مع القليل من النظام الأساسي، على افتراض برنامجك لديه الأذونات اللازمة:

[DllImport("kernel32.dll", SetLastError = true)]
static extern SafeFileHandle CreateFile(string lpFileName, uint dwDesiredAccess,
  uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition,
  uint dwFlagsAndAttributes, IntPtr hTemplateFile);

// Must close/dispose handle separately from FileStream since it's not owned by
// that object when passed to constructor.
using (SafeFileHandle h = CreateFile(longUncPath, GENERIC_WRITE, 0, IntPtr.Zero, 
       OPEN_EXISTING, 0, IntPtr.Zero))
{
    using (var fs = new FileStream(h, FileAccess.Read))
    {
        // operations with FileStream object
    }
}

يمكنك تجربة تقصير المسار عن طريق تعيين دليل أودي باستخدام Subst.exe (أو أيا كان Apis يستخدم داخليا):

http://www.makeuseof.com/tag/how-to-map-a-local-windows-folder-foldto-a-drive-letter/

من الناحية المثالية، كنت قد خريطة بعيدا قدر الإمكان للمسار.

لقد حصلت على نجاح حذف هياكل الدليل باستخدام أدناه البرنامج النصي الصغير. يستخدم PushD تنسيق UNC الذي يمنحك 32K بدلا من 260 قيدا

set "folder=\\SERVER\SHARE\DIVISION\DEPARTMENT\NAME OF TEAM - COULD BE FAIRLY LONG\" 
pushd "%folder%"
for /d %%i in ("*") do rmdir "%%i" /s /q
popd
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top