تقييم الموضوع :
  • 0 أصوات - بمعدل 0
  • 1
  • 2
  • 3
  • 4
  • 5
مراقبة نظام الملفات FileSystemWatcher
#1
كاتب الموضوع : samerselo

توفر لك الأداة FileSystemWatcher إمكانية مراقبة مجلد أو شجرة مجلدات بحيث تحصل على تنبيهات عندما يحصل أي شئ بداخلها فمثلا عندما يتم إنشاء أو حذف أو إعادة تسمية مجلد أو ملف أو عندما تتغير خصائص مجلد ما حيث تعتبر هذه الأداة ذات فائدة في العديد من الظروف فإذا كنت تقوم بعمل برنامج يقوم بتشفير الملفات آليا عندما يتم تخزينها في مجلد معين فبدون هذه الأداة سيتوجب عليك استطلاع ذلك المجلد على فترات زمنية محددة – عادة باستخدام الـ Timer – ولكن هذه الأداة تسهل عليك هذا الأمر. وممكن أن تكون هذه الأداة مفيدة عندما تقوم بتخزين ملف بيانات في الذاكرة لتسهيل الوصول إليه بسرعة ولكنك تحتاج لإعادة تحميله في الذاكرة إذا قام برنامج آخر بتغيير محتوياته.

تعريف التحكم FileSystemWatcher

يمكنك إنشاء التحكم FileSystemWatcher بإحدى طريقتين إما عن طريق الكود أو بسحبها من شريط الأدوات إلى النموذج من خلال مصمم النماذج ولا يوجد أي اختلاف في الأداء بينهما فيمكنك استخدام أي طريقة تفضلها وإنشاؤه عن طريق الكود يتم بسهولة

كود :
' Use WithEvents to be able to trap events from this object.
Dim WithEvents fsw As New FileSystemWatcher()
قبل استخدامك لهذا العنصر عليك أولا تعريف الخصائص Path و IncludeSubdirectories و Filter و NotifyFilter

فالخاصية Path تحدد مسار المجلد الذي ترغب بمراقبته لاحظ أنه سيتم إعلامك بالتغييرات داخل المجلد وليس بالتغييرات على خصائصه

والخاصية IncludeSubdirectories يجب ضبطها إلى False إذا كنت ترغب بإعلامك بالتغييرات داخل ذلك المجلد فقط أو إلى True إذا كنت ترغب بمراقبة كامل لشجرة المجلد بحيث يكون جذرها هو المجلد المحدد بالخاصية Path

والخاصية Filter تمكنك من تحديد ما هي الملفات التي تهمك فاستخدام *.* يجعلك تراقب جميع الملفات بينما استخدام *.txt يجعلك تراقب الملفات التي تملك اللاحقة txt فقط والقيمة الافتراضية لهذه الخاصية هي Null وهي تطابق *.*

والخاصية NotifyFilter مرمزة على مستوى البت bit-coded بحيث يمكنك تحديد تشكيلة من واحد أو أكثر من قيم مرقمة enumerated كـ Attributes و CreationTime و DirectoryName و FileName و LastAccess و LastWrite و Security و Size و القيمة الافتراضية لها هي LastWrite Or FileName Or DirectoryName ففي هذه الحالة لن تتلقى تنبيهات عندما تتغير الخصائص

وإليك مثال عن كيفية تعريف تحكم FileSystemWatcher من أجل التغييرات في شجرة المجلد C:\Windows

كود :
Dim WithEvents fsw As New FileSystemWatcher()

fsw.Path = "c:\windows"
fsw.IncludeSubdirectories = True ' Watch subdirectories.
fsw.Filter = "*.dll" ' Watch only DLL files.
' Add attribute changes to the list of changes that can fire events.
fsw.NotifyFilter = fsw.NotifyFilter Or NotifyFilters.Attributes
' Enable event notification.
fsw.EnableRaisingEvents = True
الحصول على التنبيهات

بعد أن تكون قد عرفت هذا العنصر بصورة صحيحة ستحصل على التنبيهات فور حدوث أي شئ حيث يمكنك تفعيل ذلك بمعالجة الأحداث أو باستخدام الطريقة WaitForChange

وأبسط طريقة للحصول على التنبيهات من FileSystemWatcher هي بكتابة معالجات للأحداث الخاصة بهذا العنصر ولكن هذه الأحداث لن تنطلق حتى تقوم بضبط الخاصية EnableRaisingEvents إلى True و تستقبل الأحداث Created و Deleted و Changed البارامتر FileSystemEventArgs الذي يعرض خاصيتان هامتان Name اسم الملف الذي وقع عليه الحدث و FullPath مسار ذلك الملف الكامل

كود :
Private Sub fsw_Created(ByVal sender As Object, _
ByVal e As FileSystemEventArgs) Handles fsw.Created
Console.WriteLine("File created: {0}", e.FullPath)
End Sub

Private Sub fsw_Deleted(ByVal sender As Object, _
ByVal e As FileSystemEventArgs) Handles fsw.Deleted
Console.WriteLine("File deleted: {0}", e.FullPath)
End Sub

Private Sub fsw_Changed(ByVal sender As Object, _
ByVal e As FileSystemEventArgs) Handles fsw.Changed
Console.WriteLine("File changed: {0}", e.FullPath)
End Sub
البارامتر FileSystemEventArgs يعرض أيضا خاصية ChangeType وهي خاصية مرقمة Enumerated حيث تخبرك بالحدث الذي وقع على الملف بحيث يمكنك استخدامها لعمل إجراء معالجة وحيد للأحداث الثلاثة السابقة

كود :
Private Sub fsw_All(ByVal sender As Object, ByVal e As FileSystemEventArgs) _
Handles fsw.Changed, fsw.Created, fsw.Deleted
Console.WriteLine("File changed: {0} ({1})", e.FullPath, e.ChangeType)
End Sub
الحدث Changed لا يستقبل أية معلومات حول نوع التغيير الذي أطلق الحدث والحدث Renamed يستقبل البارامتر RenamedEventArgs الذي يعرض خاصيتان إضافيتان هما OldName الاسم القديم و OldFullPath المسار الكامل القديم

كود :
Private Sub fsw_Renamed(ByVal sender As Object, ByVal e As RenamedEventArgs) _
Handles fsw.Renamed
Console.WriteLine("File renamed: {0} => {1}", e.OldFullPath, e.FullPath)
End Sub
ويمكن أن يكون لديك أكثر من FileSystemWatcher واحد يمكنك معالجة أحداثهم جميعا بنفس إجراء معالجة حدث واحد وعند ذلك يمكنك استخدام البارامتر الأول sender لمعرفة أي FileSystemWatcher أطلق الحدث.

يطلق FileSystemWatcher حدث مستقل لكل حدث يقع على ملف ما فعلى سبيل المثال إذا حذفت 10 ملفات ستتلقى 10 أحداث بحيث يكون لكل ملف الحدث الخاص به وكذلك إن قمت بنقل 10 ملفات من مجلد لآخر ستتلقى 10 أحداث حذف و 10 أحداث إنشاء

الطريقة WaitForChanged

إذا كان برنامجك لا يقوم بعمل أي شئ سوى انتظار التغييرات في مجلد معين أو أنك تقوم بمراقبة تغييرات الملفات من مسار ثانوي Secondary Thread يمكنك كتابة كود أبسط وأكثر فاعلية باستخدام الطريقة WaitForChanged وهي متزامنة Synchronous أي أنها لا تعود حتى يحدث تغيير ما أو ينتهي الوقت المحدد timeout وعندما تعود هذه الطريقة يستقبل البرنامج النتيجة عبر التركيب WaitForChangedResult Structure الذي تمكنك خصائصه من تحديد فيما إذا انتهت المدة أو أن حدث ما قد وقع واسم الملف المتعلق بالحدث

كود :
' Create a *new* FileSystemWatcher component with values from
' the txtPath and txtFilter controls.
Dim tmpFsw As New FileSystemWatcher(txtPath.Text, txtFilter.Text)
' Wait max 10 seconds for any file event.
Dim res As WaitForChangedResult = tmpFsw.WaitForChanged(WatcherChangeTypes.All, 10000)

' Check whether the operation timed out.
If res.TimedOut Then
Console.WriteLine("10 seconds have elapsed without an event")
Else
Console.WriteLine("Event: {0} ({1}), res.Name, res.ChangeType.ToString())
End If
الطريقة WaitForChanged تراقب فقط التغييرات في المجلد المشار إليه وتتجاهل الخاصية IncludeSubDirectories ولهذا السبب فالتركيب WaitForChangedResult Structure يعيد حقل Name فقط ولا يعيد الحقل FullPath والبارامتر الأول الذي تقوم بتمريره إلى الطريقة WaitForChanged يمكنك من تحديد نوع العملية التي تريد اعتراضها

كود :
' Pause the application until the c:\temp\temp.dat file is deleted.
tmpFsw = New FileSystemWatcher("c:\temp", "temp.dat")
tmpFsw.WaitForChanged(WatcherChangeTypes.Deleted)
Buffer Overflows
يجب عليك إدراك المشاكل المحتملة نتيجة انطلاق العديد من الأحداث خلال فترة قصيرة فالعنصر FileSystemWatcher يستخدم buffer داخلي ليتتبع أفعال نظام الملفات حتى لو كان البرنامج لا يستطيع تخديم تلك الأحداث بالسرعة الكافية وبالوضع الافتراضي يكون حجم الـ buffer هو 8KB ويمكنه تخزين حتى 160 حدث فكل حدث يأخذ 16 بايت إضافة لـ 2 بايت لكل محرف في اسم الملف وإن كنت تتوقع نشاطا أكثر فعليك زيادة حجم الـ buffer بضبط الخاصية InternalBufferSize إلى قيمة أكبر والحجم يجب أن يكون عددا صحيحا Integer مضروبا بحجم صفحة النظام ( 4KB في حالة ويندوز 2000 وما تلاه ) كما يمكنك استخدام الخاصية NotifyFilter لتحديد عدد عمليات التغيير التي تطلق الحدث Changed أو ضبط الخاصية IncludeSubdirectories إلى False إن كنت لا تحتاج لمراقبة شجرة المجلد كاملة ( يمكنك استخدام عدة عناصر FileSystemWatcher لمراقبة عدد من المجلدات إن كنت لا تحتاج لمراقبة الشجرة كاملة تحت مسار مجلد معين ) ولا يمكنك استخدام الخاصية Filter لمنع Buffer Overflowing لأنها تقوم بتصفيتها بعد أن يتم إضافتها لـ Buffer وعندما يحدث فيضان في الـ buffer سينطلق حدث خطأ

كود :
Private Sub fsw_Error(ByVal sender As Object, ByVal e As ErrorEventArgs) _
Handles fsw.Error
Console.WriteLine("FileSystemWatcher error: {0}", e.GetException().Message)
End Sub
فإن لاحظت أن برنامجك يتلقى هذا الحدث فيجب عليك تغيير إستراتيجية معالجة الأحداث لديك فمثلا يمكنك تخزين الأحدث في صف queue ثم تخديمهم عبر مسار thread آخر
معالجة المشاكل

في الحالة الافتراضية فأحداث FileSystemWatcher يتم تنفيذها على مسار مأخوذ من بركة مسارات النظام System thread pool وبما أن تحكمات Windows Forms ليست أمنة للمسارات not thread safe لذلك يجب أن لا تحاول الوصول إلى أي تحكم أو حتى النموذج نفسه من داخل أحداث التحكم FileSystemWatcher وإن وجدت هذا التصرف غير مقبول فعليك تمرير تحكم Windows Forms للخاصية SynchronizingObject كالمثال

كود :
' Use the Form object as the synchronizing object.
fsw.SynchronizingObject = Me
فالكود السابق يتأكد من أن جميع الأحداث يتم تنفيذها بنفس المسار الذي يخدم النموذج نفسه وفي Visual Studio 2005 عندما تستخدم مصمم النماذج لإنشاء العنصر FileSystemWatcher يتم ضبط هذه الخاصية تلقائيا للنموذج الذي يضم التحكم

وفيما يلي بعض الأفكار المفيدة عند التعامل مع التحكم FileSystemWatcher وبعض المشاكل التي قد تحتاج لحلها عندما تقوم باستخدامه
- يقوم التحكم بالبدء بإطلاق الأحداث عندما تكون الخاصية Path غير فارغة والخاصية EnableRaisingEvents مضبوطة إلى True كما يمكنك منعه من إطلاق الأحداث خلال طور التحميل للنموذج بتضمين أوامر التهيئة الخاصة بك بين العبارتين BeginInit و EndInit كما يفعل مصمم النماذج الخاص بفيجوال ستوديو

- في بعض الحالات قد تستقبل عدة أحدث إنشاء للملف اعتمادا على الطريقة التي يتم إنشاء الملف بها فمثلا عندما تقوم بإنشاء ملف باستخدام المفكرة Notepad ستلاحظ سلسلة من الأحداث Created و Deleted و Created و Changed

- التغيير في ملف يولد أيضا حدث إضافي في المجلد الأب أيضا لأن المجلد يحافظ على معلومات حول الملفات الموجودة داخله

- إذا كان المجلد المحدد كقيمة للخاصية Path تمت إعادة تسميته فإن التحكم FileSystemWatcher يستمر بالعمل بصورة صحيحة ولكن في هذه الحالة يستمر التحكم بإعادة الاسم القديم للمجلد وبالتالي قد تحصل على خطأ عند استخدامه وهذا يحدث بسبب أن التحكم يتعامل مع مقبض المجلد الذي لا يتغير بتغيير اسم المجلد

- إذا أنشأت مجلد ضمن المجلد الذي تتم مراقبته وكانت الخاصية IncludeSubdirectories مضبوطة على True فستتم مراقبة المجلد الجديد أيضا

- عندما يتم إنشاء ملف كبير ضمن المجلد فقد لا تستطيع قراءة كامل الملف مباشرة لأنه يكون ما يزال مملوكا من قبل العملية Process التي قامت بكتابة البيانات إلى ذلك الملف ويجب عليك حماية الكتابة إلى الملف الأصلي باستخدام حلقة Try فإن تم إطلاق خطأ يمكنك محاولة العملية بعد بضع ميلي ثانية أخرى

- عندما يقوم المستخدم بحذف ملف في مجلد فإن ملفا جديدا سيتم إنشاؤه في مجلد سلة المحذوفات RecycleBin
}}}
تم الشكر بواسطة:
#2
كاتب المشاركة : جهاد العريقي

موضوع اكثر من رائع ..

جزاك الله خير استاذ محمد سامر ..

ولي إضافة بسيطة يجب علينا عمل Imports لفضاءالاسماء IO او يمكن ان نكتب الكود الاتين

اقتباس:
[TABLE="width: 100%"]
[TR]
[TD="class: alt2"]Dim WithEvents fsw As New FileSystemWatcher() [/TD]
[/TR]
[/TABLE]

كالاتي


كود :
[color=#000000][COLOR=#0000bb]Dim WithEvents fsw [/color][color=#007700]As New [/color][color=#0000bb]IO[/color][color=#007700].[/color][color=#0000bb]FileSystemWatcher[/color][COLOR=#007700]()  
[/COLOR][color=#0000bb][/color][/COLOR]
}}}
تم الشكر بواسطة:


المواضيع المحتمل أن تكون متشابهة .
الموضوع : الكاتب الردود : المشاهدات : آخر رد
  ابسط كود لرفع الملفات عن طريق سيرفر FTP Basil Abdallah 2 3,956 20-11-20, 07:21 PM
آخر رد: walihn
Lightbulb [مقال] التعامل مع اختصارات الملفات Shortcuts Magic Sword 2 4,414 01-10-20, 11:36 AM
آخر رد: abomo3ath
  شرح انشاء برنامج تحويل صيغ الملفات الصوتيه CLARO 10 6,959 16-11-18, 04:41 PM
آخر رد: anassss
  تشفير الملفات التنفيذية silverlight 2 6,338 02-10-18, 08:57 AM
آخر رد: sendbad100
  بناء نظام ترميز ثنائي Binary Encoding silverlight 3 2,944 01-05-18, 03:12 PM
آخر رد: silverlight
  التعامل مع الملفات الصوتية ........دردشة برمجية RaggiTech 8 10,372 28-11-17, 11:23 PM
آخر رد: ahmed4240
  الملفات المؤقتة silverlight 1 2,489 05-10-17, 03:54 PM
آخر رد: sendbad100
Star [VB.NET] شرح عمل امتداد خاص لبرامجك وجعل برنامجك يقرأ هذة الملفات mohammed_gamal381 22 19,125 01-06-16, 02:55 PM
آخر رد: ابراهيم كركوكي
  الكامل في VB.Net (التعامل مع الأقراص و المجلدات و الملفات) rinawi 3 4,105 25-05-13, 01:11 PM
آخر رد: shaker.soft
  مشروع ل اخد الايقونات من الملفات just.coder 6 3,223 26-03-13, 07:12 PM
آخر رد: محمود رغمان

التنقل السريع :


يقوم بقرائة الموضوع: بالاضافة الى ( 1 ) ضيف كريم