لماذا يستغرق FSUTIL.EXE وقتا أقل لكتابة ملف ضخم في القرص من برمجيا؟

StackOverflow https://stackoverflow.com/questions/1893200

  •  19-09-2019
  •  | 
  •  

سؤال

هذا السؤال وفقا لهذا الموضوع:إنشاء ملف دمية ضخمة في غضون ثوان في C #

لقد قمت بالتحقق من FSUTIL.EXE في XP / Vista / Seven لكتابة كمية هائلة من البيانات الدمية في قرص تخزين وتستغرق وقتا أقل لكتابة ملف كبير مقارنة بالطريقة البرمجية.

عندما أحاول أن أفعل نفس الشيء بمساعدة .NET سيستغرق الأمر وقتا أكبر بكثير من fsutil.exe.

ملاحظة: أعرف أن .NET لا تستخدم الرمز الأصلي نظرا لأنني حددت هذه المشكلة مع API الأصلية أيضا متتالية:

long int size = DiskFree('L' - 64);
const char* full = "fulldisk.dsk";
__try{
Application->ProcessMessages();
HANDLE hf = CreateFile(full,
                       GENERIC_WRITE,
                       0,
                       0,
                       CREATE_ALWAYS,
                       0,
                       0);
SetFilePointer(hf, size, 0, FILE_BEGIN);
SetEndOfFile(hf);
CloseHandle(hf);
}__finally{
    ShowMessage("Finished");
    exit(0);

وكانت الإجابة متساوين مثل نتائج .NET.

ولكن بمساعدة FSUTIL.EXE، فإنه يستغرق سوى مدة أقل مما كانت عليه أعلى أو .NET يقول إنه أسرع مرتين

مثال: لكتابة 400 ميغابايت مع .NET سوف يستغرق حوالي 40 ثانية نفس المبلغ مع fsutil.exe سوف يستغرق حوالي 20secs أو أقل.

هل هناك أي تفسير حول ذلك؟ أو أي وظيفة يستخدم fsutil.exe الذي لديه سرعة هذه الأهمية للكتابة؟

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

المحلول

لا أعرف بالضبط ما يفعله FSUTIL، لكنني أعرف طريقتين لكتابة ملف كبير أسرع من ما قمت به أعلاه (أو البحث عن الطول الذي تريده وكتابة صفر، وهو ما لديه نفسه نتيجة).

المشكلة مع تلك الأساليب هي أنهم صفرين ملء الملف في ذلك الوقت الذي تقوم به الكتابة.

يمكنك تجنب ملء الصفر إما:

  1. إنشاء ملف متفرق. يتم وضع علامة على الحجم حيث تريد ذلك، ولكن البيانات غير موجودة بالفعل على القرص حتى تكتبها. جميع قراءات المناطق غير المكتوبة ستعود الأصفار.
  2. باستخدام setfilevaliddata. وظيفة لتعيين طول البيانات صالح دون زراعة الملف أولا. ومع ذلك، بسبب مشكلات الأمان المحتملة، يتطلب هذا الأمر أذونات مرتفعة.

نصائح أخرى

وأنا أتفق مع تعليق الماضي. كنت تجرؤ مع برنامج تشغيل minifilter وكان التقاط IRP_MJ_WRITE IRPS في رد الاتصال. عند إنشاء أو الكتابة إلى الملف من تطبيق CMD أو تطبيق Win32، يمكنني أن أرى يكتب ينخفض. ولكن عندما أنشأت ملف باستخدام الأمر "FSUTIL FILE CREATENEW ..."، لا أرى أي كتب. أرى هذا السلوك على Win2k8 R2 على وحدة التخزين NTFS. ولا أعتقد (غير متأكد 100٪ على الرغم من) هو ملف متفرق أيضا. من المحتمل أن تقوم بتعيين خصائص الحجم في MFT دون تخصيص أي كتلة. يقوم FSUTIL بفحص المساحة الحرة المتاحة، لذلك إذا كان حجم الملف أكبر من المساحة الحرة على القرص، فستحصل على خطأ 1.

أنا أيضا ركض برنامج shening fsctl_get_retreieval_pointers إلى الملف وحصلت على حد واحد لحجم الملف بأكمله. لكنني أعتقد أنه يحصل على جميع البيانات

هذا شيء يمكن أن يكون

  • مكتوب في المجمع (سرعة العمياء الخام)
  • رمز C / C ++ الأصلي للقيام بذلك
  • ربما دعوة نظام غير موثقة للقيام بذلك أو بعض الحيلة غير الموثقة في أي مكان.

يمكن أن تحتوي النقاط الثلاث المذكورة أعلاه على عامل كبير كبير - عندما تفكر في الأمر، عندما يتم تحميل رمز .NET، فإنه يحصل على Jit'ted بواسطة وقت التشغيل (موافق، فإن عامل الوقت لن يكون ملحوظا إذا كان لديك آلة سريعة - في النهاية المتواضعة بنتيوم، سيكون التحميل البطيء الملحوظ).

أكثر من المحتمل أن تكون قد كتبت في C / C ++. قد يفاجئك إذا كتب في المجمع.

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

آمل أن يجيب هذا على سؤالك، مع أطيب التحيات، توم.

FSUTIL سريع فقط على NTFS و Exfat، وليس على FAT32، FAT16 هذا لأن بعض نظام الملفات يحتوي على "حجم تهيئة"، وبالتالي دعم تهيئة الملفات السريعة. تحتفظ هذا فقط بالمجموعات ولكنه لا يتم تشغيله، لأنه يلاحظ في نظام الملفات أنه لم يتم كتابة أي بيانات إلى الملف وقراءة صالحة ستحصل على جميع المخازن المؤقتة المليئة بحجم 00.

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