PDA

View Full Version : مشكل در ليست كردن Subfolders ها



Delphi XE2
چهارشنبه 20 شهریور 1392, 18:13 عصر
Procedure GetDirList(InitialDir:String; DirList:TStrings);
Var
Info:TSearchRec;
Begin
If FindFirst(InitialDir + '\*.', faDirectory, Info) = 0 Then Begin
If (Info.Name <> '.') And (Info.Name <> '..') Then Begin
DirList.Add(InitialDir + '\' + Info.Name);
GetDirList(InitialDir + '\' + Info.Name, DirList);
End;

While FindNext(Info) = 0 Do
If (Info.Name <> '.') And (Info.Name <> '..') Then Begin
DirList.Add(InitialDir + '\' + Info.Name);
GetDirList(InitialDir + '\' + Info.Name, DirList);
End
End;
FindClose(Info)
End;


مشكل : اگه تو اسم فولدر نقطه به كار رفته باشه نمايشش نميده

یوسف زالی
چهارشنبه 20 شهریور 1392, 21:12 عصر
سلام.
این کد رو تست کنید، با کمی تغییر می تونید به اونچه که می خواهید برسید.
موفق باشید.


procedure TForm1.Surfe(Path, Find: string; Lst: TStrings);
var
F: TSearchRec;
begin
if FindFirst(Path + '\*', faAnyFile, F) = 0 then
begin
if DirectoryExists(Path + '\' + F.Name) then
begin
if (F.Name <> '.') and (F.Name <> '..') then
Surfe(Path + '\' + F.Name, Find, Lst);
end
else if StrMatch(UpperCase(F.Name), UpperCase(Find)) then
Lst.Add(Path + '\' + F.Name);

while FindNext(F) = 0 do
if DirectoryExists(Path + '\' + F.Name) then
begin
if (F.Name <> '.') and (F.Name <> '..') then
Surfe(Path + '\' + F.Name, Find, Lst);
end
else if StrMatch(UpperCase(F.Name), UpperCase(Find)) then
Lst.Add(Path + '\' + F.Name);
end;
end;

BORHAN TEC
چهارشنبه 20 شهریور 1392, 21:45 عصر
سلام
در نسخه های جدید دلفی (دلفی 2010 و نسخه های جدیدتر) دیگه لازم نیست از اون کدهای قدیمی(پست بالا) استفاده کنید. پیشنهاد می کنم که از این کدی مثل این استفاده کنید:
program Project4;

{$APPTYPE CONSOLE}
{$R *.res}

uses
System.SysUtils,
System.IOUtils; // before delphi xe2 => "IOUtils"

var
S: string;

const
SourceDir = 'C:\IRKEY3\Application\Dumps';

begin
for S in TDirectory.GetDirectories(SourceDir, TSearchOption.soAllDirectories,
function(const Path: string; const SearchRec: TSearchRec): Boolean
begin
Result := True;
end) do
Writeln(S);

Readln;

end.
موفق باشید...

یوسف زالی
چهارشنبه 20 شهریور 1392, 21:48 عصر
شاهین چرا من این کد رو نمی فهمم؟!
اون function چیه اون وسط قلمبه؟
:کف:

BORHAN TEC
چهارشنبه 20 شهریور 1392, 22:19 عصر
شاهین چرا من این کد رو نمی فهمم؟!
بخاطر اینکه در مورد توابع بی نام مطالعه نکردی. :چشمک:
خوب مشکلی نیست الان کامل توضیح میدم.
تاریخچه:
در زمان دلفی 2009 موارد متعددی به نحو زبان دلفی اضافه شد که یکی از مهمترین آنها متدهای بدون نام بود. این قابلیت توسط یکی از قویترین اعضای تیم سازنده کامپایلر دلفی یعنی آقای Barry Kelly (http://stackoverflow.com/users/3712/barry-kelly) به دلفی اضافه شد. این شخص سال گذشته شرکت Embarcadero رو ترک کرد. :ناراحت: البته مشکل خاصی نیست. اگه پولی که به اینها میدن رو نصفش رو به من بدن سه برابر قابلیت اضافه می کنم. جدی نگیرید، شوخولوق اِلَدِم. :لبخند:

میریم که در مورد کد توضیح بدیم:
System.IOUtils;
خط بالا کاملاً واضحه. رکوردهای TDirectory و TPath و TFile درون این یونیت قرار داره. پیشنهاد می کنم که به کدهای این یونیت نگاه کنی.

TDirectory.GetDirectories
در حالت کلی استفاده از این قسمت یک مقدار از نوع TStringDynArray بر میگرداند. اگر به یونیت System.Types دقت کنی میبینی که این نوع به صورت زیر تعریف شده:
TStringDynArray = array of string;

طبق یونیت IOUtils ساختار TDirectory.GetDirectories به این صورته:
class function TDirectory.GetDirectories(const Path: string;
const SearchOption: TSearchOption;
const Predicate: TFilterPredicate): TStringDynArray;
-در پارامتر اول مسیر پوشه ای را میدهیم که می خواهیم در آن عمل جستجو را انجام دهیم.
- در پارامتر دوم نوع جستجو را مشخص می کنیم. اگر مقدار این پارامتر TSearchOption.soAllDirectories باشد، تمام زیر پوشه ها مورد جستجو قرار می گیرند و اگر TSearchOption.soTopDirectoryOnly باشد فقط داخل همان پوشه عمل جستجو انجام میشود و عملیات جستجو بر روی زیر پوشه ها انجام نمیشود.
- نوع استفاده شده در پارامتر سوم از نوع TFilterPredicate است که تعریف آن به این شکل است:
TFilterPredicate = reference to function(const Path: string;
const SearchRec: TSearchRec): Boolean;
به عبارت ساده تر در پارامتر سوم TDirectory.GetDirectories می توانیم از یک تابع بدون نام استفاده کنیم که همانطور که گفتم توابع بدون نام در دلفی 2009 معرفی شد.

در کدی که در پست قبل قرار دادم به قسمت زیر دقت کن:
function(const Path: string; const SearchRec: TSearchRec): Boolean
begin
Result := True;
end
معنی Result := True چیه؟
جواب: یعنی این که می خواهیم تمام پوشه ها رو چاپ کنیم. به عبارت دیگه اگه مقدار برگشتی این تابع بدون نام True باشه خط زیر اجرا میشه:
Writeln(S);
افتاد؟
اگه نیوفتاد یک مثال دیگه میزنم.
می خواهیم نام پوشه هایی رو چاپ کنیم که با حرف A شروع می شوند.
جواب:
program Project4;

{$APPTYPE CONSOLE}
{$R *.res}

uses
System.SysUtils,
System.IOUtils; // before delphi xe2 => "IOUtils"

var
S: string;

const
SourceDir = 'C:\IRKEY3\Application\Dumps';

begin
for S in TDirectory.GetDirectories(SourceDir, TSearchOption.soAllDirectories,
function(const Path: string; const SearchRec: TSearchRec): Boolean
begin
Result := (SearchRec.Name[1] = 'A');
end) do
Writeln(S);

Readln;

end.

یک نکته دیگه. دلیل استفاده از for in چیه؟؟؟
جواب: برای پیمایش یک TStringDynArray می توانیم از کدی مثل این استفاده کنیم:
var
MyStringDynArray: TStringDynArray;
S: String;
begin
// ...

for S in MyStringDynArray do
Writeln(S);
end;

همین! :لبخند:

یوسف زالی
چهارشنبه 20 شهریور 1392, 22:32 عصر
افتاد؟

:قهقهه:
توابع بی نام رو یک جا در کارهای آقای کشاورز دیده بودم، فکر کردم فقط همون جا کاربرد داشته.
توضیحات خوبی دادی. ممنون.
حدس زدم چی به چیه ولی خواستم دقیقش رو بگی که زحمتش رو کشیدی ولی چرا تو آموزش هات نیست؟ هان؟! هان؟! (این آموزش چند تا لایک داره؟ هان؟!)
:لبخند:
باید برم دوباره What is new این ورژن رو ببینم.
بازم ممنون

BORHAN TEC
چهارشنبه 20 شهریور 1392, 22:39 عصر
فکر کردم فقط همون جا کاربرد داشته.
خیلی جاهای دیگه کاربرد داره مثلاً استفاده از TThread و ... .

توضیحات خوبی دادی. ممنون.
قابلی نداشت. :چشمک:

ولی چرا تو آموزش هات نیست؟ هان؟! هان؟! (این آموزش چند تا لایک داره؟ هان؟!)
حاجی 24 ساعت آموزش دلفی در واقعیت مباحث مبتدی رو هم شامل نمیشه، چه برسه به متوسط و حرفه ای. من نمیدونم که نویسندگان این کتابها چطوری و با چه اعتماد به نفسی روی کتاب 500 صفحه ای مینویسن مرجع کامل؟!!! :متفکر:

باید برم دوباره What is new این ورژن رو ببینم.
حتماً این کار رو بکن مخصوصاً کتابهای Marco Cantu و کتاب Delphi XE2 Foundations.
یا حق...

Felony
پنج شنبه 21 شهریور 1392, 08:05 صبح
می خواهیم نام پوشه هایی رو چاپ کنیم که با حرف A شروع می شوند.
نیازی به استفاده از Anonymous Method تو همچین موارد ساده ای نیست :


var
S: string;
const
SourceDir = 'C:\IRKEY3\Application\Dumps\';
begin
for S in TDirectory.GetDirectories(SourceDir, 'A*',
TSearchOption.soAllDirectories) do
Memo1.Lines.Add(S);
end;

* برای گرفتن لیست فایل ها باید از متد GetFiles استفاده بشه .

Delphi XE2
پنج شنبه 21 شهریور 1392, 10:41 صبح
نیازی به استفاده از Anonymous Method تو همچین موارد ساده ای نیست :


var
S: string;
const
SourceDir = 'C:\IRKEY3\Application\Dumps\';
begin
for S in TDirectory.GetDirectories(SourceDir, 'A*',
TSearchOption.soAllDirectories) do
Memo1.Lines.Add(S);
end;

* برای گرفتن لیست فایل ها باید از متد GetFiles استفاده بشه .

سلام اين كد شما مسير رو هم توي ممو ميريزه

براي اين كه نتيجه فقط اسم پوشه ها بشه چيكار كنك

Felony
پنج شنبه 21 شهریور 1392, 12:06 عصر
براي اين كه نتيجه فقط اسم پوشه ها بشه چيكار كنك
ExtractFileName !!!