الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

سؤال :في كود البحث عن ملف بالكمبيوتر

بدأه ayash في 29 أبريل 2010 · 9 رد · 867 مشاهدة · في الأسئلة المجابة
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم

اذا ممكن كود البحث عن ملف بالكمبيوتر

اعطيه اسم الملف وبعطيني مساره

وهل يوجد طريقه بحث في الجهاز recursivly

وشكرا

291964_260506123967115_206850989332629_1001538_45132_n.jpg

اللهم إني أعوذ بك من علم لا ينفع ، ومن قلب لا يخشع ، ومن نفس لا تشبع ، ومن دعوة لا يستجاب لها

#2

استخدم بحث الويندوز :mad:

مدونتي: C++ Tips and Tricks

#3

السلام عليكم ...

لم تحدد نظام التشغيل, و المكتبات التي تستخدمها, و لا ماذا تريد عمله من إيجاد ملف معين, و لا خيارات البحث كالتوقف عند إيجاد ملف بذلك الاسم, أو إكمال البحث لإيجاد باقي الملفات المشابهة في الاسم في مجلدات أخرى. عموماً, أنا استخدمت boost لإنجاز الأمر, و هي تعمل بكل تأكيد على نظامك مهما كان :)

الكود يقوم بإيجاد __جميع__ مسارات الملفات بالاسم الذي يدخله المستخدم, و يجب عليك تحديد مسار أولي لكي يبدأ البحث من خلاله:

#include <iostream>
#include <string>
#include <vector>
#include <boost/filesystem.hpp>

using namespace std;
using namespace boost::filesystem;

void find_file(const path& root, const string& file_name, vector<path>& found_files)
{
	directory_iterator current_file(root), end_file;
	for( ; current_file != end_file; ++current_file)
	{
		if( is_directory(current_file->status()) )
			find_file(*current_file, file_name, found_files);
		if( current_file->leaf() == file_name )
		{
			// No more than two files with same name in the same directory,
			// add the file to found_files and exit.
			found_files.push_back(*current_file);
			break;
		}
	}
}

int main()
{
	string file_name;
	string root_path;
	vector<path> found_files;

	std::cout << root_path();
	cout << "Please enter the name of the file to be found(with extension): ";
	cin >> file_name;
	cout << "Please enter the starting path of the search: ";
	cin >> root_path;
	cout << endl;

	find_file(root_path, file_name, found_files);
	for( std::size_t i = 0; i < found_files.size(); ++i)
		cout << found_files << endl;
}

هناك الكثير من التحسينات التي قد تقوم بها, و لكن لا أعتقد أنها لازمة إن كان الاستخدام بسيطاً, و ربما تحتاج إلى استخدام دوال النظام الذي تعمل عليه, لجعل الكود أسرع من هذه الطريقة أو لإضافة خيارات أكثر لعملية البحث.

تحياتي....

تم تعديل هذه المشاركة بواسطة Khaled.Alshaya في 29 أبريل 2010 في 23:50

5
#4

معلش يا أخ خالد, ليا تعليقي بسيط,

بما إني مبرمج جافا , فلي ملاحظه,,

الدله :

find_file

, هذه الداله المفروض أنا تأخذ معطيات و تعطي نتائج, على هيئة vector , فلم لم تجعل هذه الداله ترجع هذا ال vector؟

أعرف أنك تستغل ميزه ال call by reference, فلم فضلت هذه الخاصيه على أن ترجع vector بالنتائج؟؟

#5
اقتباس
أعرف أنك تستغل ميزه ال call by reference, فلم فضلت هذه الخاصيه على أن ترجع vector بالنتائج؟؟

بسبب تجنب الـ Memory Allocation، لإنك حين تعود بـ Vector ستحتاج لأن تحجز مساحته داخل الـ Heap بإستخدام new (على افتراض انه لا يوجد memory manager) و بالتالى لابد من استخدام delete لتحريره و فى حالة النسيان سيحدث memory leak و باقى الأمور المزعجه المتعلقه بالـ memory managment، اما عندما يتم العوده من خلال parameter فيمكن ان يكون مكان المتغير الذى يتم تمرير للداله داخل الـ stack اى هو automatic variable و بالتالى تحرير الذاكره سيتم بشكل تلقائى بمجرد الخروج من الداله.

و الله ولى التوفيق

تم تعديل هذه المشاركة بواسطة Muhammad alaa في 30 أبريل 2010 في 01:32

1

مدونتي: C++ Tips and Tricks

#6
اقتباس
أعرف أنك تستغل ميزه ال call by reference, فلم فضلت هذه الخاصيه على أن ترجع vector بالنتائج؟؟

ملاحظة عظيمة :)

لأن عملية الإرجاع ستكون مكلفة. فلو قمنا بالتالي:

vector<path> found_files = find_file(...);

طبعاً, الـ vector الموجود في الدالة سيكون على الـ stack الخاص بها. بينما الـ vector الذي حصلنا عليه موجود على الـ stack في الدالة main على سبيل المثال.

لاحظ أن ذلك كلام عام. لأن معظم المترجمات الشهيرة تقوم بعمل Optimization اسمه RVO و هو يعني Return Value Optimization, بمعنى أن العائد من الدالة سوف يوضع على الـ Stack في الدالة التي نادت دالة أخرى مباشرة, دون حجز شيء على stack الدالة المناداة. الحل الآخر أن تقوم باستخدام المؤشرات, أو المؤشرات الأوتوماتيكية كـ auto_ptr من المكتبة القياسية أو shared_ptr الأكثر قوة من boost, و يصبح الأمر مثل استخدام الـ GC. بشكل عام, لا يحبذ استخدام المؤشرات لأن استخدامها يجب أن يكون للضرورة فقط عندما لا يمكن إنجاز الأمر بدونها. الحل المختصر هو أن تقوم بعمل out parameter.

طبعأً لو كان الأمر راجع لي و الكود لي لكنت قمت بكتابة الكود بـ Cpp0x خصوصاً أن GCC 4.5 أصبح يدعمه بشكل شبه كامل قبل سنة من اكتمال الـ Standards :P

يمكن أن أكتب الكود بـ Cpp0x إن أحببت, و هناك ميزة الـ Move Constructor التي تلغي جميع المشاكل التي تكلمنا عنها من حيث عملية النسخ. حيث يصبح السطر الذي وضعناه في الأعلى اعتيادياً جداً, دون الحاجة إلى استخدام المؤشرات أو القلق حول عملية النسخ.

1
#7

شكرا إخوتي :blink:

#8

مشكورين اخواني

جزيل الشكر

----------------------------

من علمني حرفا كنت له عبدا

291964_260506123967115_206850989332629_1001538_45132_n.jpg

اللهم إني أعوذ بك من علم لا ينفع ، ومن قلب لا يخشع ، ومن نفس لا تشبع ، ومن دعوة لا يستجاب لها

#9
اقتباس
من علمني حرفا كنت له عبدا

أخى انت عبد لله فقط وقولك هذا به شرك و لعياذ بالله، من فضلك احذفها.

و الله ولى التوفيق

1

مدونتي: C++ Tips and Tricks

#10

السلام عليكم ...

أعتذر عن خطأ بسيط في الكود الذي في الأعلى :)

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

#include <iostream>
#include <string>
#include <vector>
#include <boost/filesystem.hpp>

using namespace std;
using namespace boost::filesystem;

void find_file(const path& root, const string& file_name, vector<path>& found_files)
{
	directory_iterator current_file(root), end_file;
	bool found_file_in_dir = false;
	for( ; current_file != end_file; ++current_file)
	{
		if( is_directory(current_file->status()) )
			find_file(*current_file, file_name, found_files);
		if( !found_file_in_dir && current_file->leaf() == file_name )
		{
			// Now we have found a file with the specified name,
			// which means that there are no more files with the same
			// name in the __same__ directory. What we have to do next,
			// is to look for sub directories only, without checking other files.
			found_files.push_back(*current_file);
			found_file_in_dir = true;
		}
	}
}

int main()
{
	string file_name;
	string root_path;
	vector<path> found_files;

	std::cout << root_path;
	cout << "Please enter the name of the file to be found(with extension): ";
	cin >> file_name;
	cout << "Please enter the starting path of the search: ";
	cin >> root_path;
	cout << endl;

	find_file(root_path, file_name, found_files);
	for( std::size_t i = 0; i < found_files.size(); ++i)
		cout << found_files << endl;
}

ملاحظة حول الكود في المشاركة الأولى أيضاً, هي السطر التالي:

        std::cout << root_path();

لا أدري من أين أتت الأقواس, رغم أن الكود الموجود لدي على الجهاز لايحتوي على تلك الأقواس, ربما بسبب التعديل اليدوي في المحرر الظريف في المنتدى :(

تحياتي...

تم تعديل هذه المشاركة بواسطة Khaled.Alshaya في 1 مايو 2010 في 20:04

مواضيع مشابهة