منتدى فيجوال بيسك لكل العرب | منتدى المبرمجين العرب
اسلوب الأستدعاء الذاتى و مدخل الى تطبيقات اكثر كفائة و عملية - نسخة قابلة للطباعة

+- منتدى فيجوال بيسك لكل العرب | منتدى المبرمجين العرب (http://vb4arb.com/vb)
+-- قسم : قسم لغة الفيجوال بيسك VB.NET (http://vb4arb.com/vb/forumdisplay.php?fid=182)
+--- قسم : قسم مقالات VB.NET (http://vb4arb.com/vb/forumdisplay.php?fid=184)
+--- الموضوع : اسلوب الأستدعاء الذاتى و مدخل الى تطبيقات اكثر كفائة و عملية (/showthread.php?tid=4800)



اسلوب الأستدعاء الذاتى و مدخل الى تطبيقات اكثر كفائة و عملية - RaggiTech - 02-10-12

كاتب الموضوع : egyption-coder



تصنيف الموضوع للمبرمج المتوسط و لن يعنى المتقدمين كثيرا
__________________________________________________ _



صغر حجم الكود .. استهلاك اقل للذاكرة
اعتقد ان هذه الأمور من اهم ما يشغل المطورين و المبرمجين فى جميع اللغات
ناهيك عن برامج لا يمكن تطبيقها الا بهذا الأسلوب
مثل مستكشف الويندوز (windows Explorer) او برامج مضادات الفيروسات أو برامج الكراك أو الألعاب..الخ
بالطبع الموضوع قديم و لكن نظرا لأمكانية تجاهله فقد تجاهله الكثير من المبرمجين و بعضهم يتجنبه
اما البعض الأخر فيكتفى بنظرة خاطفة على الموضوع ثم يتحول عنه

ان اسلوب الأستدعاء الذاتى قد بدأ استخدامه منذ الأصدارات الأولى من الفيجوال بيزيك و قد اصبح من الصعب تجنبه بعد ظهور الفيجوال دوت نت و هو ذلك الأجراء الذى يقوم باستدعاء نفسه بنفسه

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

و سوف اقوم كذلك بشرح اسلوب تعامل الذاكرة مع اسلوب الأستدعاء الذاتى

و سيكون مرجعى فى ذلك الماسترنج بتصرف منى لأصل الى ما ذكرت من نتائج و الله المستعان

و ان رأى الأخوة ان الموضوع قديم او لا يستحق فأرجو ابلاغى توفيرا للوقت و المساحة

اولا لكى نعرف الفكرة التى يقوم عليها الأستدعاء التلقائى اريدك ان تضع تصورا لما نريد

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

لعل الأمر يبدو معقدا قليلاً خاصة للمبتدئين و لكنه ليس كذلك و سيظهر كم الأمر بسيطا بالمثال التالى


تخيل انك تبحث عن كتاب فى منزل و المنزل به عدد من الغرف و كل غرفة بها عدد من الصناديق و الكتب
بعض الكتب خارج الصناديق و بعض الصناديق يحتوى على صناديق اصغر بالأضافة الى الكتب

لا بد انك ستدخل الغرفة الأولى و تفتح اول صندوق ثم تبحث فى محتويات الصندوق فأن كانت كتب قرأت عناوينها و ان وجدت صندوق اخر توقفت عن القراءة ثم قمت بنفس العملية مع الصندوق الثانى

و هنا لنا وقفة....... ان قلنا ان فتح الصندوق و قرائة عناوين الكتب هو دالة

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


حسنا لا بد من مثال بسيط يوضح لنا الأمر

هل تذكر ما هو المعامل

ان معامل الرقم ن و الذى يرمز له بـ !ن
يساوى ن × !(ن-1) (الا معامل الصفر فهو دائما يساوى 1)
و بما ان معامل (ن-1)
يساوى (ن-1) × !(<ن-1> -1) يساوى (ن-1) × !(ن-2)
و هكذا فأن
معامل الرقم 4 و الذى يرمز له بالرمز !4
يكون كالتالى
!4 = 4 × !3
= 4×3×!2
=4×3×2×!1
=4×3×2×1×!0
=4×#×2×1×1
= 24


اعتقد انك فهمت ما اقصده تقريباً

ان المعادلة هى
معامل ن = ن × معامل (ن-1)
و اذا كان ن = 0 اذن معامل ن = 1

و لعمل دالة تحسب معامل n

كود :
function facNO (n as integer) as double
if n = 0 then
facNo = 1
Else
facNo = n * facNo ( n-1)
End if
End function
كبرناها و هى صغيرة

ان الأستدعاء التلقائى هنا هو فى السطر


كود :
facNo = n * facNo ( n-1)
فى الواقع هنا سيتم الأنتهاء من المعامل الخاص بالصفر اولا
ثم معامل الواحد ثم معامل الأثنين و هكذا

و السبب هو ان معامل الأربعة ينتظر و تنطلق الدالة التى تم استدعائها (نفس الدالة تستدعى بطلب من نفسها)
و هى الدالة التى تحسب معامل الثلاثة ثم تنتظر و تنطلق دالة الأثنين و هكذا
حتى تنتهى دالة حساب معامل الصفر من عملها فتتبعها دالة حساب معامل الواحد و هكذا



و لكن ما علاقة هذا بمسح المجلدات

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


اسلوب الأستدعاء الذاتى و مدخل الى تطبيقات اكثر كفائة و عملية - RaggiTech - 02-10-12

من الأفضل قبل كتابة اى اجراء تلقائى ان نكتب تصور عام للكود الخاص به
و بما اننا لن نحتاج الى ان نعود بقيمة فى التطبيق الذى سنبدأ به
و هو تطبيق يقوم بمسح الملفات على الجهاز
بما اننا لن نحتاج الى ان نعود بقيمة فى هذا التطبيق فأننا سنحتاج الى روتين فرعى
و يعمل هذا الروتين على مسح محتويات مجلد و يكون الروتين كالأتى
sub ScanFolder ( current_folder)
'بعض العمليات على ملفات هذا المجلد

كود :
if current_folder contains subfolders
for each subfolder
ScanFolder ( current_folder)
next
end if
هذا هو التصور المبدئى للكود
و لكى نقوم بتحويل هذا التصور الى كود
سنحتاج الى انشاء مشروع ويندوز ابليكاشن
و نضيف زر و نسميه سكان و نضيف ليست بوكس لعرض محركات الأقراص التى ستظهر تباعا طبقا للمحرك اذى يتم عمل سكان له
و نضيف ليست بوكس اخر للمجلدات و اخر للملفات

و الأن سنحتاج الى القيام بالكود الأتى
كود الزر سكان

كود :
for each drive in my pc
scanFolder(this drive)
next
طبعا هذا تصور للكود

و ألأن مع الروتين scanFolder

كود :
for each directory in this drive
ScanFolder ( current_folder)
next
اما عن الروتين ScanFolder
فقد وضعنا تصوره سابقا

و الأن مع الأكواد


اسلوب الأستدعاء الذاتى و مدخل الى تطبيقات اكثر كفائة و عملية - RaggiTech - 02-10-12

الأن مع الكود المبدئى
و لا اعتقد انه يحتاج الى شرح و مع ذلك
ان شاء الله ارفق مثال



كود :
Public Class Form1
Public curDrive As String
Public dir As String

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'هنا نستدعى محركات الأقراص و نبدأ العمل عليها بالتتالى

Dim drives() As String
drives = System.IO.Directory.GetLogicalDrives
Dim iDrive As Integer

On Error Resume Next ' نضعها لأننا لم نحدد بعد كيف نتعامل مع الملفات المغلقة و المضغوطة
For iDrive = 0 To drives.GetUpperBound(0)

curDrive = drives(iDrive)
ListBox1.Items.Add(curDrive)
'now scan folders
scanFOLDER()
Next


End Sub
Sub scanFOLDER()
'هنا نستدعى المجلدات الرئيسية لكل محرك و نبدأ مسحها بالتتالى
Dim directories() As String
directories = System.IO.Directory.GetDirectories(curDrive)


On Error Resume Next ' نضعها لأننا لم نحدد بعد كيف نتعامل مع الملفات المغلقة و المضغوطة




For Each dir In directories
ListBox2.Items.Add(dir)
'now scan files or sub folders
scanFiles(dir)
Next

End Sub

Sub scanFiles(ByVal ddir As String)
'هنا نستخدم الأستدعاء الذاتى لمسح المجلدات و الملفات لكل مجلد رئيسى
Dim rupt As Boolean

If Button1.Text = "scan" Then
Button1.Text = "stop scan"
rupt = False
Else

Button1.Text = "scan"
rupt = True
End If

If rupt Then
Exit Sub
End If
Dim dirr As String
Dim ffile As String
Dim fi As IO.FileInfo
On Error Resume Next ' نضعها لأننا لم نحدد بعد كيف نتعامل مع الملفات المغلقة و المضغوطة
For Each ffile In System.IO.Directory.GetFiles(ddir)
fi = New IO.FileInfo(ffile)
ListBox3.Items.Add(fi.Name & vbTab & fi.Length & vbTab & fi.CreationTime)

Next
For Each dirr In System.IO.Directory.GetDirectories(ddir)
Application.DoEvents()
scanFiles(dirr)
Next



End Sub
End Class



اسلوب الأستدعاء الذاتى و مدخل الى تطبيقات اكثر كفائة و عملية - RaggiTech - 02-10-12

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