PDA

View Full Version : جستجوی فایلهای خاص



Mask
چهارشنبه 02 تیر 1389, 19:02 عصر
با سلام
بنده با استفاده از دستورات finde file میتونیم لیست کلیه فایلهای یه مسیر رو بدست بیارم و در یک لیست بریزم.
سوالم اینه مثلا من فقط نام فایلهایی که پسوند bmp و jpg داشته باشه رو میخام.
چطوری باید چنین فیلتری ایجاد کرد.
ممنون.

tdkhakpur
چهارشنبه 02 تیر 1389, 20:20 عصر
خب داخل حلقه جستجو خودتان فیلتر برای بررسی نوع فایل قرار بدید!
اگر منظورتان استفاده از متد آماده برای این کار باشد مطمئننا همان کاری هست که شما انجام میدید و تفاوتی با سایر جستجو ها ندارد.

SAASTN
چهارشنبه 02 تیر 1389, 20:43 عصر
خود FindFirst این قابلیت رو داره، کافیه متن جستجو رو (*.bmp) به مسیر جستجو اضافه کنید. یه مثال ساده تو ضمیمه هست. فقط از OpenDialog استفاده کردم که باید یه فایل رو انتخاب کنید تا کار کنه.

tdkhakpur
چهارشنبه 02 تیر 1389, 21:11 عصر
خود FindFirst این قابلیت رو داره،

ما که نگفتیم ندارد!
منظور از ارسال تاپیک بالا بررسی سرعت پیدا کردن فایلها بود!:لبخندساده:

Mask
پنج شنبه 10 تیر 1389, 16:53 عصر
ممنون از دوستان
یا استفاده از کد زیر مشکل حل شد.

procedure TfrmMain.btnClick(Sender: TObject);
var
F : TSearchRec;
FileName : TFileName;
Path : string;
begin
lst.Items.BeginUpdate;
try
lst.Clear;
Path := IncludeTrailingBackslash(edtPath.Text);
if (FindFirst(Path + '*.exe',faAnyFile - faDirectory,F) = 0)
then
try
repeat
FileName := F.Name;
lst.Items.Add(F.Name)
until FindNext(F) <> 0;
finally
FindClose(F);
end;
finally
lst.Items.EndUpdate;
end;
end;
end.
حالا مشکل اینجاست که من همزمان و برای صرفه جویی در وقت ، میخام 3 نوع فایل جستجو و برام لیست بشه.
اینو چیکار باید کرد.

Felony
پنج شنبه 10 تیر 1389, 16:54 عصر
در نخ های جداگانه پردازش کنید ، یعنی برای هر نوع فایل یک نخ .

Mask
پنج شنبه 10 تیر 1389, 16:57 عصر
ممنون
منضورم اینه که در همین کد 2 نوع فایل جستجو بشه.

tdkhakpur
جمعه 11 تیر 1389, 00:43 صبح
procedure TfrmMain.btnClick(Sender: TObject);
var
F : TSearchRec;
FileName : TFileName;
Path : string;
tmpName: string;
begin
lst.Items.BeginUpdate;
try
lst.Clear;
Path := IncludeTrailingBackslash(edtPath.Text);
if (FindFirst(Path + '*.*',faAnyFile - faDirectory,F) = 0) // *.exe اصلاح
then
try
repeat
FileName := F.Name;
tmpName := ExtractFileExt(F.Name);
if (tmpName='.COM') or (tmpName='.BMP') or (tmpName='.JPEG') then // مثال
lst.Items.Add(F.Name)
until FindNext(F) <> 0;
finally
FindClose(F);
end;
finally
lst.Items.EndUpdate;
end;
end;
end.

Mask
جمعه 11 تیر 1389, 13:50 عصر
ممنون از دوستان
چرا کد زیر مشکل داره و اجرا نمیشه؟

unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
edtPath: TEdit;
lst: TListBox;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
public
end;
Type
MyThread = Class(TThread)
protected
procedure Execute; override;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure MyThread.Execute;
var
F : TSearchRec;
FileName : TFileName;
Path : string;
begin
lst.Items.BeginUpdate;
try
lst.Clear;
Path := IncludeTrailingBackslash(edtPath.Text);
if (FindFirst(Path + '*.com',faAnyFile - faDirectory,F) = 0)
then
try
repeat
FileName := F.Name;
lst.Items.Add(F.Name)
until FindNext(F) <> 0;
finally
FindClose(F);
end;
finally
lst.Items.EndUpdate;
end;
end;
end;
////
procedure TForm1.FormCreate(Sender: TObject);
var
T : MyThread;
begin
T := MyThread.Create(True);
T.FreeOnTerminate := true;
T.Resume;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
F : TSearchRec;
FileName : TFileName;
Path : string;
begin
lst.Items.BeginUpdate;
try
lst.Clear;
Path := IncludeTrailingBackslash(edtPath.Text);
if (FindFirst(Path + '*.exe',faAnyFile - faDirectory,F) = 0)
then
try
repeat
FileName := F.Name;
lst.Items.Add(F.Name)
until FindNext(F) <> 0;
finally
FindClose(F);
end;
finally
lst.Items.EndUpdate;
end;
end;
end.

Mask
دوشنبه 14 تیر 1389, 13:16 عصر
دوستان یه نگاهی هم اینور بندازن.

tdkhakpur
دوشنبه 14 تیر 1389, 13:26 عصر
داخل پروسه زیر


procedure TForm1.FormCreate(Sender: TObject);
var
T : MyThread;
begin
T := MyThread.Create(True);
T.FreeOnTerminate := true;
T.Resume;
end;
تعریف ترد را عمومی کنید یعنی بیرون از پروسه ببرید.(دلیل آزاد شدن حافظه ترد قبل از اتمام پروسه انجام میشود)


var
T : MyThread;
procedure TForm1.FormCreate(Sender: TObject);
begin
T := MyThread.Create(True);
T.FreeOnTerminate := true;
T.Resume;
end;

Mask
دوشنبه 14 تیر 1389, 14:28 عصر
ممنون
اصلا کد کار نمیده.
دلیلش چیه؟

tdkhakpur
دوشنبه 14 تیر 1389, 14:46 عصر
خب کلاسی که از ترد مشتق شده نمیتواند از اشیاع فرم چیزی بداند به همین دلیل کامپایلر نمیتواند نوع داده های استفاده شده در ترد را تشخیص دهد.


unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
lst: TListBox;
Button1: TButton;
edtPath: TEdit;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
public
end;
Type
MyThread = Class(TThread)
protected
procedure Execute; override;
end;
var
T : MyThread;
Form1: TForm1;
implementation
{$R *.dfm}
procedure MyThread.Execute;
var
Sender: TObject;
begin
Form1.Button1Click(Sender);
end;
////
procedure TForm1.FormCreate(Sender: TObject);
begin
T := MyThread.Create(True);
T.FreeOnTerminate := true;
T.Resume;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
F : TSearchRec;
FileName : TFileName;
Path : string;
begin
lst.Items.BeginUpdate;
try
lst.Clear;
Path := IncludeTrailingBackslash(edtPath.Text);
if (FindFirst(Path + '*.exe',faAnyFile - faDirectory,F) = 0)
then
try
repeat
FileName := F.Name;
lst.Items.Add(F.Name)
until FindNext(F) <> 0;
finally
FindClose(F);
end;
finally
lst.Items.EndUpdate;
end;
end;
end.

vcldeveloper
دوشنبه 14 تیر 1389, 17:37 عصر
خب کلاسی که از ترد مشتق شده نمیتواند از اشیاع فرم چیزی بداند به همین دلیل کامپایلر نمیتواند نوع داده های استفاده شده در ترد را تشخیص دهد.ارتباطی به مشتق شدن از TThread نداره، بلکه شما در هر شی ایی بخواید به اجزاء یک شی دیگه دسترسی داشته باشید، باید نام شی مربوطه را قید کنید، یا از with استفاده کنید، پس وقتی در کد MyThread می نویسید lst، اون کلاس (MyThread) نمیدونه شما دارید به چه چیزی اشاره می کنید! چون lst جزئی از کلاس TForm1 هست، و باید از طریق یک نمونه شی از اون کلاس (مثلا Form1) در دسترس قرار می گرفت: Form1.lst.

اما، حتی اگر شما Form1 را هم به ابتدای تمامی اون خطوط مشکل دار در کد موجود در پست شماره 9 تاپیک اضافه کنید، هم کد نوشته شده غلط هست.

کد نوشته شده توسط tdkhakpur (http://www.barnamenevis.org/forum/member.php?u=99732) در پست شماره 13 هم غلط هست.

علت غلط بودن هر دو کد، تغییر در عناصر گرافیکی رابط کاربر، از طریق Threadایی غیر از Thread اصلی برنامه هست. شما نباید در داخل یک Thread دیگه به ListBox چیزی اضافه کنید. در ضمن، در کد موجود در پست شماره 13، اگر هم بر فرض می خواستیم یک Event-handler را فراخوانی کنیم، نباید به اون شکل یک متغیر محلی Sender تعریف کنیم، و به Event-handler پاس بدیم! اگر چیزی برای پاس دادن به اون متد ندارید، باید بهش nil پاس بدید. الان اون متغیر Sender تعریف شده در اون کد، میتونه Nil باشه، یا یک مقدار تصادفی در stack داشته باشه. اگر Event-handler مربوطه از پارامتر Sender استفاده می کرد، ممکن بود هر اتفاقی رخ بده، چون مقدار Sender تصادفی هست، و میتونه حتی واقعا به یک داده مجاز اشاره بکنه، که در اون صورت، ممکن بود برنامه در اون لحظه کار کنه، ولی به خاطر ایجاد خرابی در حافظه، در جای دیگه ایی از برنامه مشکلی رخ بده، بدون اینکه بتونید به این راحتی متوجه ربط اون مشکل با این کد بشید!

استفاده از Thread این نیست که یک کلاس جدید از TThread مشتق کنیم، و هر چی کد قبل از این داشتیم، بریزیم در داخل متد Execute آن، و در انتظار معجزه بشینیم!

یک توصیه جدی به برنامه نویسانی که آشنایی کافی با مفهوم Thread و چگونگی استفاده از آن ندارند، این هست که از Thread استفاده نکنند! استفاده کردن از Thread بدون داشتن اطلاعات کافی درباره آن و چگونگی استفاده اش، میتونه مشکلاتی بسیار بزرگ تر از اون بهینه سازی که فرضا از طریق استفاده از Thread به دست آوردید، براتون به ارمغان بیاره!


برای اون کدی هم که نوشتید، ساده ترین کاری که می تونید انجام بدید این هست که؛
1- تمام کدهای مربوط به دسترسی به اجزاء فرم را در کد Thread حذف کنید، و فقط کد جستجو را باقی بزارید.
2- یک فیلد از نوع TStringList در داخل کلاس MyThread ایجاد کنید.
3- در داخل کد جستجو، نام فایل های پیدا شده را به این فیلد جدید اضافه کنید.
4- در داخل فرم، یک Event-handler برای رویداد OnTerminate مربوط به MyThread بنویسید، و در داخل آن، مقدار فیلد StringList ساخته شده در مرحله 1 رو به مقدار lst.Items اختصاص بدید.

اینطوری هر زمان که کار جستجو تمام شد، نتایج پیدا شده، به ListBox مربوطه منتقل میشند. راه های دیگه ایی هم هست، ولی این راه ساده ترین راهی بود که به ذهنم رسید.

tdkhakpur
دوشنبه 14 تیر 1389, 20:06 عصر
ارتباطی به مشتق شدن از TThread نداره، بلکه شما در هر شی ایی بخواید به اجزاء یک شی دیگه دسترسی داشته باشید، باید نام شی مربوطه را قید کنید، یا از with استفاده کنید، پس وقتی در کد MyThread می نویسید lst، اون کلاس (MyThread) نمیدونه شما دارید به چه چیزی اشاره می کنید! چون lst جزئی از کلاس TForm1 هست، و باید از طریق یک نمونه شی از اون کلاس (مثلا Form1) در دسترس قرار می گرفت: Form1.lst.


خب شما یه دستی به کد میزدید متوجه می شدید که باید این شکلی جواب بدید همه میدانند که باید با with و یا استفاده از نام فرم داخل توابعی که عضو نیستند برای استفاده از اجرائ فرم لازم هست.

کد نوشته شده توسط tdkhakpur (http://www.barnamenevis.org/forum/member.php?u=99732) در پست شماره 13 هم غلط هست.

نه درسته!!


علت غلط بودن هر دو کد، تغییر در عناصر گرافیکی رابط کاربر، از طریق Threadایی غیر از Thread اصلی برنامه هست. شما نباید در داخل یک Thread دیگه به ListBox چیزی اضافه کنید. در ضمن، در کد موجود در پست شماره 13، اگر هم بر فرض می خواستیم یک Event-handler را فراخوانی کنیم، نباید به اون شکل یک متغیر محلی Sender تعریف کنیم، و به Event-handler پاس بدیم! اگر چیزی برای پاس دادن به اون متد ندارید، باید بهش nil پاس بدید.
اولا کد رو من ننوشتم فقط ایرادشان را رفع کردم دوما کدها ارسال شده به عنوان مثال هشتند نه برنامه ای که مستقیما به کار برده شدوند.

الان اون متغیر Sender تعریف شده در اون کد، میتونه Nil باشه، یا یک مقدار تصادفی در stack داشته باشه. اگر Event-handler مربوطه از پارامتر Sender استفاده می کرد، ممکن بود هر اتفاقی رخ بده، چون مقدار Sender تصادفی هست، و میتونه حتی واقعا به یک داده مجاز اشاره بکنه، که در اون صورت، ممکن بود برنامه در اون لحظه کار کنه، ولی به خاطر ایجاد خرابی در حافظه، در جای دیگه ایی از برنامه مشکلی رخ بده، بدون اینکه بتونید به این راحتی متوجه ربط اون مشکل با این کد بشید!

تمام مطالبی که ارسال کردید با شرط همراه هست و کلا در این مورد غلطه.
اون sender برای متد پاس داده شده و هیچ استفاده ای هم ازش نشده و فعلا خطری ندارد ولی بهتر بود میگفتید نباید از sender استفاده شود که بدون شک همه هم میدانند که استفاده از sender که قبلا ایجاد نشده میتواند عامل خطا در نرم افزار باشد.

vcldeveloper
سه شنبه 15 تیر 1389, 05:27 صبح
خب شما یه دستی به کد میزدید متوجه می شدید که باید این شکلی جواب بدید همه میدانند که باید با with و یا استفاده از نام فرم داخل توابعی که عضو نیستند برای استفاده از اجرائ فرم لازم هست.
اگر همه می دونستند که باید از یک شی استفاده کنند، اون وقت چرا کاربر مربوطه در پست شماره 9 اون سوال رو مطرح کرد؟


اولا کد رو من ننوشتم فقط ایرادشان را رفع کردم دوما کدها ارسال شده به عنوان مثال هشتند نه برنامه ای که مستقیما به کار برده شدوند.
مسئله اینه که شما ایرادات کد را رفع نکردید، فقط کاری کردید که کد کامپایل بشه! البته به روشی غلط! قرار نیست کد شما مستقیما به کار برده بشه، بلکه کد شما یک رفتار غلط رو آموزش میده. درباره غلط بودنش هم در پست قبلی توضیح دادم که چرا غلط هست! یه ListBox رو داخل یه Thread فرعی پر کردید، حالا مدعی هم هستید که کدتان درست بوده؟!


تمام مطالبی که ارسال کردید با شرط همراه هست و کلا در این مورد غلطه.
اون sender برای متد پاس داده شده و هیچ استفاده ای هم ازش نشده و فعلا خطری ندارد ولی بهتر بود میگفتید نباید از sender استفاده شود که بدون شک همه هم میدانند که استفاده از sender که قبلا ایجاد نشده میتواند عامل خطا در نرم افزار باشد.
عزیز جان، هر متغیری که به صورت Local روی Stack تعریف میکنید، باید Initialize بشه؛ یک متغیر مقداردهی اولیه نشده رو به یک متد دیگه پاس دادید، در شرایطی که این کارت میتونه در یک برنامه جدی موجب مشکلات مختلف در پایداری و حتی امنیت نرم افزار و سیستم بشه! این کد رو به عنوان مثال غلط نوشتید که کاربران با دیدن آن، از نوشتن همچین کدهایی پرهیز کنند؟! یا برای تمرین سایر کاربران همچین اشتباهات فاحشی در اون انجام دادید؟!

این مدل کد نوشتن و مثال زدن که کاربر بیچاره رو از چاله در میاره، میاندازه توی چاه!

tdkhakpur
سه شنبه 15 تیر 1389, 12:58 عصر
یه ListBox رو داخل یه Thread فرعی پر کردید، حالا مدعی هم هستید که کدتان درست بوده؟!

خب به این پست یک نگاهی بیندازید بعد نظر بدید که کد مال چه کسی بوده؟
http://barnamenevis.org/forum/showpost.php?p=1029209&postcount=5


هر متغیری که به صورت Local روی Stack تعریف میکنید، باید Initialize بشه؛ یک متغیر مقداردهی اولیه نشده رو به یک متد دیگه پاس دادید، در شرایطی که این کارت میتونه در یک برنامه جدی موجب مشکلات مختلف در پایداری و حتی امنیت نرم افزار و سیستم بشه!

نه همچین کاری هم نیست فقط یک استفاده بیجا از پشته صورت میگیرد و تا وقتی از این پارامتر پاس داده شده استفاده نشود ایرادی ندارد.

این کد رو به عنوان مثال غلط نوشتید که کاربران با دیدن آن، از نوشتن همچین کدهایی پرهیز کنند؟! یا برای تمرین سایر کاربران همچین اشتباهات فاحشی در اون انجام دادید؟!

نه به این شکلها هم نیست کابری که به این حد رسیده و سوالات تخصصی میپرسه میداند که چه عملی باید انجام بده تا کد درست اجرا بشود.


این مدل کد نوشتن و مثال زدن که کاربر بیچاره رو از چاله در میاره، میاندازه توی چاه!
این نظر شماست هر کس میتواند به اندازه لازم از کدها استفاده کند.

vcldeveloper
سه شنبه 15 تیر 1389, 13:45 عصر
خب به این پست یک نگاهی بیندازید بعد نظر بدید که کد مال چه کسی بوده؟
http://barnamenevis.org/forum/showpo...09&postcount=5 (http://barnamenevis.org/forum/showpost.php?p=1029209&postcount=5)
اون مربوط به زمانی هست که کد را برای Thread اصلی نوشته بود.

در پست شماره 9 (http://www.barnamenevis.org/forum/showpost.php?p=1029816&postcount=9)، همان کد را Copy\Paste کرد داخل متد Execute یک Thread، و کد اجر نشد؛ در نتیجه پست شماره 9 را ارسال کرد، تا ببینه مشکل کدش چی هست.

در پست شماره 13 (http://www.barnamenevis.org/forum/showpost.php?p=1032551&postcount=13)، شما به جای اینکه مشکل کدش را بهش تذکر بدید، همون اشتباه خودش را تکرار کردید، با این تفاوت که فقط کد را تغییر دادید که کامپایل بشه.

پس هم کد Delphi-7 غلط هست، هم اون اصلاحیه ایی که شما براش انجام دادید، غلط هست!


نه همچین کاری هم نیست فقط یک استفاده بیجا از پشته صورت میگیرد و تا وقتی از این پارامتر پاس داده شده استفاده نشود ایرادی ندارد.
مگه شما پیاده سازی همه متدهایی که فراخوانی می کنید رو خودتون انجام میدید؟! حتی اگرهم که انجام می دادید (که نمیدید)، باید بدونید که MyThread یک کلاس مستقل هست، و Form1 هم یک کلاس مستقل. در یک پروژه جدی هم هر کدام از این کلاس ها را ممکنه افراد مختلفی بنویسند. شما نمی تونید هر چیزی که خواستید به متدی از یک کلاس ارسال کنید، به خیال اینکه این پارامتر چیز مهمی نیست! کد شما دقیقا یک روش اشتباه برنامه نویسی هست. من هم روی اینجور اشتباهات حساس هستم، چون اینجا یک سایت آموزشی هست. دوست ندارم کاربران این سایت با دیدن کدهایی که به شیوه ایی غلط نوشته میشند، در این سایت گمراه بشند. شما اصلا متوجه پارامتر Sender و نقش اون نشدید، بلکه دیدید اون متد یک پارامتر Sender از نوع TObject میگیره، شما هم روی Stack یه متغیر با همون نام و نوع ایجاد کردید، و به متد مربوطه پاس دادید.


نه به این شکلها هم نیست کابری که به این حد رسیده و سوالات تخصصی میپرسه میداند که چه عملی باید انجام بده تا کد درست اجرا بشود.
عجب! اگر می دونست که اون شیوه اشتباه هست که کد اشتباه خودش را اینجا نمیگذاشت، و از دیگران برای اصلاح آن کمک نمی خواست!


این نظر شماست هر کس میتواند به اندازه لازم از کدها استفاده کند.
از کد اصلاحی که شما نوشتید، فقط میشه به عنوان یک مثال غلط در استفاده از Threadها استفاده کرد؛ یعنی این کد رو آورد، و به دانشجویان نشان داد که هیچ وقت نباید برای یک Thread همچین کدی بنویسند.

ببین دوست عزیز، من حوصله کل کل ندارم...کدی که نوشتید، شیوه ایی غلط هست، هم تعریف متغیر به اون شکل و پاس دادنش به یک متد دیگه بدون مقداردهی اولیه کردن آن (چون اون متد بدبخت هیچ راهی برای چک کردن صحت مقدار Sender نداره)؛ و هم کدی که برای Thread اصلاح کردید. حالا شما میخواید قبول کنید، میخواید قبول نکنید. برای من مهم نیست که شما اشتباه بودن کدتان را قبول کنید یا نه؛ این مطالب رو اینجا نوشتم که کاربرانی که این تاپیک رو می بینند، با دیدن کد به اصطلاح اصلاحی شما، دچار اشتباه نشند، و از این شیوه شما در کدهای خودشان استفاده نکنند.

Mask
سه شنبه 15 تیر 1389, 13:57 عصر
با سلام

ببین دوست عزیز، من حوصله کل کل ندارم...
حاجی خونسردیتو حفظ کن.:لبخند::قلب:
ممنون از دوست خوبم خانم/آقای خاکپور.
با استفاده از کده، سرچ شما و فرمایشات علی آقا مشکل بنده حل شد.
افرادی مثل بنده (آماتور) ، یه مقدار در مورد مسایلی مثل ترید ضعیف هستیم . که با محبت دوستان و صبور بودنشون برای یادگیریه افرادی مثل بنده ، امید وارم که چنین مطالبی برامون تفهیم بشه.
بازم ممنون از دو دوست خوبم.