PDA

View Full Version : جست وجوی فایل...



rezarko
شنبه 05 فروردین 1391, 01:43 صبح
سلام. خواستم ببینم چه جوری میشه یه برنامه ساخت که مثلاً فایل "test.txt" را از هر جای سیستم که باشه پیدا کنه و اون رو توی درایو c کپی کنه؟
ممنون

رافعی مهدی
شنبه 05 فروردین 1391, 12:03 عصر
سلام

این کار رو به دو مرحله اصلی تقسیم میکنیم:
1- یافتن فایل مورد نظر
2- کپی کردن آن در مسیر دلخواه

1- یافتن فایل مورد نظر:
قبل از هر چیز باید از فضای نام System.IO در برنامه استفاده کنید.
ابتدا لازمه لیست تمام درایوهای سیستم رو داشته باشیم. متد Directory.GetLogicalDrives این لیست رو به ما میده.

توجه 1: این متد، تمام درایوهای سیستم، اعم از CD-Drive، Memory-Stick، External HDD و ... رو برمیگردونه.

حالا باید در تمام این درایوها دنبال فایل مورد نظر بگردیم. شاید بهترین گزینه برای انجام این کار استفاده از متد بازگشتی باشه. بنابراین میخواهیم متدی بنویسیم که در صورت نیاز خودش رو فراخوانی کنه. این متد یک Directory رو دریافت میکنه، لیست فایلها و پوشه های داخل اون رو میگیره، ابتدا بین لیست فایلها جستجو میکنه، اگر پیدا نشد به سراغ لیست پوشه های داخل مسیر اولیه (که به عنوان آرگومان به این متد داده بودیم) میرود و خودش رو برای تک تک اونها فراخوانی میکنه. به این ترتیب هر یک از این فراخوانی ها به نوبه خود فراخوانی های مورد نیاز رو انجام میدهند و کل فایلها و پوشه ها داخل مسیر اولیه جستجو میشوند.

توجه 2: برای بدست آوردن فایلهای داخل یک مسیر، از متد GetFiles از کلاس DirectoryInfo استفاده شده. اگر برنامه شما در سیستم مقصد مشکلی در دسترسی به فایلها نداشته باشه، این متد تمام فایلها اعم از فایلها با Attributeهایی نظیر Hidden، System و ... رو برمیگردونه.

توجه 3: برای بدست آوردن پوشه های داخل یک مسیر (Subdirectories) از متد GetDirectories از همان کلاس استفاده شده است.

بر اساس این توضیحات، متد بازگشتی مورد نظر، به صورت زیر خواهد بود:


/// <summary>
/// Tries to find a file within given directory and all of its sub-directories recursively.
/// </summary>
/// <param name="directory">A directory as the root path to be searched.</param>
/// <param name="fileName">Name of file to be looked for. (e.g. "test.txt")</param>
/// <returns>If the file is found, return value will be its full-name, otherwise null.</returns>
private string FindFile(string directory, string fileName)
{
//
// Gathering all required information about given directory..
//
DirectoryInfo currentDirInfo = new DirectoryInfo(directory);

FileInfo[] fileInfoes = currentDirInfo.GetFiles();
DirectoryInfo[] dirIndoes = currentDirInfo.GetDirectories();

//
// Looking for specified file within the file list from the current directory..
//
foreach (FileInfo fileInfo in fileInfoes)
{
if (fileInfo.Name == fileName)
return fileInfo.FullName;
}

//
// Looking for specified file within the subdirectories of the current directory..
//
foreach (DirectoryInfo dirInfo in dirIndoes)
{
//
// Recursive call..
//
string result = FindFile(dirInfo.FullName, fileName);

if (result != null)
return result;
}

return null;
}

برای استفاده از این متد، کافی است از یک حلقه for بر روی ریشه (Root) تمام درایوهای سیستم استفاده کنیم:


/// <summary>
/// Looks for given file name within all logical drives.
/// </summary>
/// <param name="fileName">Name of file to be looked for. (e.g. "test.txt")</param>
private void GlobalFind(string fileName)
{
bool found = false;
string[] logicalDrives = Directory.GetLogicalDrives();

for (int index = 0; index < logicalDrives.Length; index++)
{
//
// Looking for specified file within index-th drive..
//
string result = FindFile(logicalDrives[index], fileName);

if (result != null)
{
found = true;
break;

//
// Doing the 2nd step..
//
}
}

if (!found)
{
// ToDo: Announce it!
}
}


2- کپی کردن فایل در مسیر دلخواه:
خب، حالا نوبت به کپی کردن فایل پیدا شده در مسیر دلخواه میرسه. همانطور که در کد مربوط به متد GlobalFind ملاحظه کردید، بخشی با کامنت Doing the 2nd step مشخص شده بود که برای این کار در نظر گرفته شده است. کپی کردن فایل به این صورت انجام میشه که شما نام کامل فایل مبدأ (شامل مسیر فایل + نام فایل + extension فایل) رو به همراه نام کامل فایل مقصد به متد استاتیک Copy از کلاس System.IO.File میدهید و در صورتی که خطایی رخ ندهد این کار صورت میگیره.

توجه 4: نام کامل فایل مقصد، نامی دلخواه است و نباید فایلی با آن نام در مسیری که تعیین میکنید وجود داشته باشد.

توجه 5: برای دستیابی به خطاهای احتمالی هر متد، Caret رو بر روی نام آن متد (در اینجا Copy) قرار داده و دکمه های Ctrl+K, I رو فشار بدهید. لیست Exception های آن، در زیر توضیحات مربوطه به نمایش در خواهد آمد.

بر اساس این توضیحات متد GlobalFind رو به شکل زیر اصلاح میکنیم:


/// <summary>
/// Looks for given file name within all logical drives and then copies it into the given destination.
/// </summary>
/// <param name="fileName">Name of file to be looked for. (e.g. "test.txt")</param>
/// <param name="destinationFileName">The destination file name. (e.g. @"C:\found1.txt")</param>
private void GlobalFind(string fileName, string destinationFileName)
{
bool found = false;
string[] logicalDrives = Directory.GetLogicalDrives();

for (int index = 0; index < logicalDrives.Length; index++)
{
//
// Looking for specified file within index-th drive..
//
string result = FindFile(logicalDrives[index], fileName);

if (result != null)
{
found = true;

//
// Copying the found file to the given destination..
//
try
{
File.Copy(result, destinationFileName);
}
catch
{
// ToDo: Handle it!
}
break;
}
}

if (!found)
{
// ToDo: Announce it!
}
}

نکته پایانی: چنانچه جابجا شدن فایلها در برنامه شما مهم است، یکی از بهترین گزینه ها، استفاده از کلاس System.IO.FileSystemWatcher هست که هرگونه تغییر در یک مسیر یا فایل رو زیر نظر میگیره و رخدادهای متناظر با اون رو raise میکنه. برای اطلاعات بیشتر در این مورد اینجا (http://www.codeproject.com/Articles/26528/C-Application-to-Watch-a-File-or-Directory-using-F) رو ببینید.

rezarko
شنبه 05 فروردین 1391, 17:38 عصر
ممنون
میشه یه لطف کنید یه نمونه up کنید؟

asadegha
یک شنبه 06 فروردین 1391, 05:26 صبح
دوستمون لطف کردن همه کد ها رو گذاشته توضیحات کامل هم داده. شما لطف کن خودت بنویس ذهن و دستت بیاد تو کار. کار آماده تنبلت میکنه، جلوی پیشرفتتو میگیره.