PDA

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



qasemf
دوشنبه 04 اسفند 1399, 02:05 صبح
سلام چطور میشه مثلا یه فایلی با نام test.php رو با سرعت بالا و بدون کندی سیستم جستجو کرد ?? از thread هم استفاده اما نمیدونم چرا اتفاقی رخ نمیده ؟

Mahmoud.Afrad
سه شنبه 05 اسفند 1399, 02:43 صبح
اگر کدتون جواب نمیده یا کدتون اینجا بزارید یا اصلا سوال نپرسید چون ما نمیتونیم ندیده ، مشکل رو حل کنیم. کد آماده هم ...

coolergas
سه شنبه 05 اسفند 1399, 06:21 صبح
سلام
منم این مشکل رو دارم

qasemf
چهارشنبه 06 اسفند 1399, 15:00 عصر
ببینید مشکل این هست که زمانی که میخواد دایرکتوری های یک درایو رو یکی یکی بخونه به دایرکتوری system volume information و recyclebin میرسه پیغام access denied میده!! خیلی جستجو زدم معمولا گفته بودن باید از try catch استفاده کرد اما باز هم جواب نمیده به روش های مختلف این کار رو کردم اما نشده این هم یکی از نمونه هایی هست که تست کردم و جواب نمیده

foreach (var drive in drives)
{
if (drive.IsReady)
{
try
{
var allFiles = Directory.GetFiles(drive.ToString(), ".*", SearchOption.AllDirectories);
FileList.Items.Add(allFiles.ToString());
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
}

barnamenevisjavan
چهارشنبه 06 اسفند 1399, 16:07 عصر
ببینید مشکل این هست که زمانی که میخواد دایرکتوری های یک درایو رو یکی یکی بخونه به دایرکتوری system volume information و recyclebin میرسه پیغام access denied میده!! خیلی جستجو زدم معمولا گفته بودن باید از try catch استفاده کرد اما باز هم جواب نمیده به روش های مختلف این کار رو کردم اما نشده این هم یکی از نمونه هایی هست که تست کردم و جواب نمیده

foreach (var drive in drives)
{
if (drive.IsReady)
{
try
{
var allFiles = Directory.GetFiles(drive.ToString(), ".*", SearchOption.AllDirectories);
FileList.Items.Add(allFiles.ToString());
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
}


اون Exception رو با این UnauthorizedAccessException جایگزین کنید

barnamenevisjavan
چهارشنبه 06 اسفند 1399, 16:09 عصر
ببینید مشکل این هست که زمانی که میخواد دایرکتوری های یک درایو رو یکی یکی بخونه به دایرکتوری system volume information و recyclebin میرسه پیغام access denied میده!! خیلی جستجو زدم معمولا گفته بودن باید از try catch استفاده کرد اما باز هم جواب نمیده به روش های مختلف این کار رو کردم اما نشده این هم یکی از نمونه هایی هست که تست کردم و جواب نمیده

foreach (var drive in drives)
{
if (drive.IsReady)
{
try
{
var allFiles = Directory.GetFiles(drive.ToString(), ".*", SearchOption.AllDirectories);
FileList.Items.Add(allFiles.ToString());
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
}


یه راه ساده تری هم وجود داره اینکه از لینک استفاده کنید و اگر پوشه سیستمی بود سلکت نکنید من توی یکی از برنامه هام به این صورت استفاده کردم
foreach (var item in dir.GetDirectories()
.Where(s => !s.Attributes.HasFlag(FileAttributes.System))
.Where(s => !s.Attributes.HasFlag(FileAttributes.Hidden))
{
Console.WriteLine(item.Name + " Deleted");
item.Delete(true);
}

qasemf
پنج شنبه 07 اسفند 1399, 01:58 صبح
یه راه ساده تری هم وجود داره اینکه از لینک استفاده کنید و اگر پوشه سیستمی بود سلکت نکنید من توی یکی از برنامه هام به این صورت استفاده کردم
foreach (var item in dir.GetDirectories()
.Where(s => !s.Attributes.HasFlag(FileAttributes.System))
.Where(s => !s.Attributes.HasFlag(FileAttributes.Hidden))
{
Console.WriteLine(item.Name + " Deleted");
item.Delete(true);
}




ببینید چون بحث سرعت هم مطرح هست من اومدم به این روش عمل کردم و از parallel استفاده کردم واسه همین الان این شرطی که شما گفتین رو نمیتونم پیادش کنم


private void WalkDirectoryTree(DirectoryInfo dr, string searchname)

{

System.IO.FileInfo[] files = null;
System.IO.DirectoryInfo[] subDirs = null;
try
{
files = dr.GetFiles(searchname + ".*");
if (files != null)
{
if (InvokeRequired)
{
Invoke((MethodInvoker)delegate () {

foreach (FileInfo fi in dr.GetFiles(searchname + ".*")
.Where(f => !f.Attributes.HasFlag(FileAttributes.System))
.Where(s => !s.Attributes.HasFlag(FileAttributes.Hidden)))


{
flowLayoutPanel2.Controls.Clear();
listview_Control.Filelist.Items.Add(fi.Name);
flowLayoutPanel2.Controls.Add(listview_Control);

// allFiles.Add(fi);
}
});
}

subDirs = dr.GetDirectories();

Parallel.ForEach(subDirs, dwr => WalkDirectoryTree(dwr, searchname)


);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}


}

barnamenevisjavan
پنج شنبه 07 اسفند 1399, 08:37 صبح
ببینید چون بحث سرعت هم مطرح هست من اومدم به این روش عمل کردم و از parallel استفاده کردم واسه همین الان این شرطی که شما گفتین رو نمیتونم پیادش کنم


private void WalkDirectoryTree(DirectoryInfo dr, string searchname)

{

System.IO.FileInfo[] files = null;
System.IO.DirectoryInfo[] subDirs = null;
try
{
files = dr.GetFiles(searchname + ".*");
if (files != null)
{
if (InvokeRequired)
{
Invoke((MethodInvoker)delegate () {

foreach (FileInfo fi in dr.GetFiles(searchname + ".*")
.Where(f => !f.Attributes.HasFlag(FileAttributes.System))
.Where(s => !s.Attributes.HasFlag(FileAttributes.Hidden)))


{
flowLayoutPanel2.Controls.Clear();
listview_Control.Filelist.Items.Add(fi.Name);
flowLayoutPanel2.Controls.Add(listview_Control);

// allFiles.Add(fi);
}
});
}

subDirs = dr.GetDirectories();

Parallel.ForEach(subDirs, dwr => WalkDirectoryTree(dwr, searchname)


);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}


}

شما شرط رو روی فایل گذاشتید، باید روی دایرکتوری قرار بدید
var subDirs = dr.GetDirectories()
.Where(f => !f.Attributes.HasFlag(FileAttributes.System))
.Where(s => !s.Attributes.HasFlag(FileAttributes.Hidden));

the king
پنج شنبه 07 اسفند 1399, 11:24 صبح
روالی با پردازش موازی کارکرد سریعتری داره که اجرای همزمانش عملی باشه و تداخلی ایجاد نکنه.
درخواست جستجوی سیستم فایل اگه شبیه جستجو در یک لیست بود، با تقسیم کردن لیست به چند قسمت و جستجوی موازی هر قسمت طبعا سریعتر میشد، اما همچین روالی نداره.
زمانی که داده درایو در حافظه RAM بافر شد میشه پردازش موازی انجام داد برای همینه که جستجوی بار دوم خیلی سریعتر از دفعه اول انجام میشه، ولی دیگه تا این داده ها بافر بشه زمان زیادی سپری شده.
رابط خوندن و نوشتن درایو مشترک ئه، در حین خوندن بخشی از سیستم فایل از درایو نمیتونه همزمان بخش دیگری رو بخونه. حتی اگه درایو روی دیسک مکانیکی باشه که دیگه بدتر هد مدام باید بین دو بخش جابجا بشه و بجای اینکه در مجموع سریعتر بشه عملا کندتر میشه.
برای همین موقعی که سیستم عامل داره از یک درایو داده میخونه یا می نویسه هر پردازش دیگری که با اون درایو سر و کار داره کند میشه، چه درخواست با نخ مجزا باشه و چه برنامه دیگری.

qasemf
پنج شنبه 07 اسفند 1399, 16:18 عصر
روالی با پردازش موازی کارکرد سریعتری داره که اجرای همزمانش عملی باشه و تداخلی ایجاد نکنه.
درخواست جستجوی سیستم فایل اگه شبیه جستجو در یک لیست بود، با تقسیم کردن لیست به چند قسمت و جستجوی موازی هر قسمت طبعا سریعتر میشد، اما همچین روالی نداره.
زمانی که داده درایو در حافظه RAM بافر شد میشه پردازش موازی انجام داد برای همینه که جستجوی بار دوم خیلی سریعتر از دفعه اول انجام میشه، ولی دیگه تا این داده ها بافر بشه زمان زیادی سپری شده.
رابط خوندن و نوشتن درایو مشترک ئه، در حین خوندن بخشی از سیستم فایل از درایو نمیتونه همزمان بخش دیگری رو بخونه. حتی اگه درایو روی دیسک مکانیکی باشه که دیگه بدتر هد مدام باید بین دو بخش جابجا بشه و بجای اینکه در مجموع سریعتر بشه عملا کندتر میشه.
برای همین موقعی که سیستم عامل داره از یک درایو داده میخونه یا می نویسه هر پردازش دیگری که با اون درایو سر و کار داره کند میشه، چه درخواست با نخ مجزا باشه و چه برنامه دیگری.


مهندس ممنونم از نظرتون...
فکر میکنین راه حل چیه؟ الان با کمک دوست عزیز barnamenevisjavan (https://barnamenevis.org/member.php?205725-barnamenevisjavan) مشکل عدم دسترسی حل شد اما کماکان برنامه کند عمل میکنه و نتیجه ای هم نداره!!! میشه زمانی که جستجو میخواد اتفاق بیافته از thread استفاده کرد؟ اخه چند جا خوندم که میگفتن از thread باید استفاده کرد.هرچند باز هم نتیجه نگرفتم...
barnamenevisjavan (https://barnamenevis.org/member.php?205725-barnamenevisjavan) شما هم نظری در این رابطه دارین؟

daniyaltjm
پنج شنبه 07 اسفند 1399, 21:33 عصر
برای جستجوی سریع در هارد، خود شرکت مایکروسافت هم از ایندکس استفاده میکنه دیگه راهی نیست مگه اینکه از ssd استفاده کنید.

barnamenevisjavan
پنج شنبه 07 اسفند 1399, 21:36 عصر
مهندس ممنونم از نظرتون...
فکر میکنین راه حل چیه؟ الان با کمک دوست عزیز barnamenevisjavan (https://barnamenevis.org/member.php?205725-barnamenevisjavan) مشکل عدم دسترسی حل شد اما کماکان برنامه کند عمل میکنه و نتیجه ای هم نداره!!! میشه زمانی که جستجو میخواد اتفاق بیافته از thread استفاده کرد؟ اخه چند جا خوندم که میگفتن از thread باید استفاده کرد.هرچند باز هم نتیجه نگرفتم...
barnamenevisjavan (https://barnamenevis.org/member.php?205725-barnamenevisjavan) شما هم نظری در این رابطه دارین؟
من زیاد از کد شما متوجه نشدم که دارید چیکار میکنید ولی من با کد زیر تمام فایل های یک پوشه (که شامل پوشه های تو در تو هست) رو پیدا میکنم 4000 فایل رو توی 2 ثانیه برمیگردونه
public static IEnumerable<string> EnumerateManifest(string rootDirectory)
{
foreach (var directory in Directory.GetDirectories(
rootDirectory,
"*",
SearchOption.AllDirectories))
{
foreach (var file in Directory.GetFiles(directory))
{
yield return file;
}
}
}


اینم همون متده فقط با پارالل
//public static IEnumerable<string> EnumerateManifest(string rootDirectory)
//{
// var result = new BlockingCollection<string>();

// var files = Directory.EnumerateFiles(rootDirectory, "*", SearchOption.AllDirectories);
// Parallel.ForEach(files, (file) =>
// {
// result.Add(file);
// });
// return result;
//}

qasemf
جمعه 08 اسفند 1399, 04:07 صبح
خیلی جالبه 153066
باز هم خطای عدم دسترسی میده