نمایش نتایج 1 تا 7 از 7

نام تاپیک: جستجو در همه هارد

  1. #1

    جستجو در همه هارد

    سلام

    من می خواهم وقتی که برنامه ام اجرا می شود ابتدا دنبال یک فایل با پسوند مشخصی بگردد


    چه جوری می توانم که این کار را انجام دهم؟

    ممنون

  2. #2
    بنیان گذار Barnamenevis آواتار مهدی کرامتی
    تاریخ عضویت
    اسفند 1381
    محل زندگی
    کرج، گلشهر
    سن
    46
    پست
    6,379
    <div dir=ltr>
    Problem/Question/Abstract:
    How to perform a file search including subdirectories

    Solve 1:
    Recursively scanning all drives:
    &#123;excerpt from form declaration, form has a listbox1 for the  results, a label1 for progress, a button2 to start the scan, an edit1 to get the search mask from, a button3 to stop the scan.&#125;
    private
    &#123; Private declarations &#125;
    FScanAborted&#58; Boolean;
    public
    &#123; Public declarations &#125;

    function ScanDrive&#40;root, filemask&#58; string; hitlist&#58; TStrings&#41;&#58; Boolean;

    function TForm1.ScanDrive&#40;root, filemask&#58; string; hitlist&#58; TStrings&#41;&#58; Boolean;

    function ScanDirectory&#40;var path&#58; string&#41;&#58; Boolean;
    var
    SRec&#58; TSearchRec;
    pathlen&#58; Integer;
    res&#58; Integer;
    begin
    label1.caption &#58;= path;
    pathlen &#58;= Length&#40;path&#41;;
    &#123; first pass, files &#125;
    res &#58;= FindFirst&#40;path + filemask, faAnyfile, SRec&#41;;
    if res = 0 then
    try
    while res = 0 do
    begin
    hitlist.Add&#40;path + SRec.Name&#41;;
    res &#58;= FindNext&#40;SRec&#41;;
    end;
    finally
    FindClose&#40;SRec&#41;
    end;
    Application.ProcessMessages;
    Result &#58;= not &#40;FScanAborted or Application.Terminated&#41;;
    if not Result then
    Exit;
    &#123;second pass, directories&#125;
    res &#58;= FindFirst&#40;path + ' *.* ', faDirectory, SRec&#41;;
    if res = 0 then
    try
    while &#40;res = 0&#41; and Result do
    begin
    if &#40;&#40;Srec.Attr and faDirectory&#41; = faDirectory&#41; and &#40;Srec.name &lt;> ' . '&#41;
    and &#40;Srec.name &lt;> ' .. '&#41; then
    begin
    path &#58;= path + SRec.name + '\';
    Result &#58;= ScanDirectory&#40;path&#41;;
    SetLength&#40;path, pathlen&#41;;
    end;
    res &#58;= FindNext&#40;SRec&#41;;
    end;
    finally
    FindClose&#40;SRec&#41;
    end;
    end;

    begin
    FScanAborted &#58;= False;
    Screen.Cursor &#58;= crHourglass;
    try
    Result &#58;= ScanDirectory&#40;root&#41;;
    finally
    Screen.Cursor &#58;= crDefault
    end;
    end;

    procedure TForm1.Button2Click&#40;Sender&#58; TObject&#41;;
    var
    ch&#58; Char;
    root&#58; string;
    begin
    root &#58;= 'C&#58;\';
    for ch &#58;= 'A' to 'Z' do
    begin
    root&#91;1&#93; &#58;= ch;
    case GetDriveType&#40;Pchar&#40;root&#41;&#41; of
    DRIVE_FIXED, DRIVE_REMOTE&#58;
    if not ScanDrive&#40;root, edit1.text, listbox1.items&#41; then
    Break;
    end;
    end;
    end;

    procedure TForm1.Button3Click&#40;Sender&#58; TObject&#41;;
    begin &#123;aborts scan&#125;
    fScanAborted &#58;= True;
    end;


    Solve 2:
    procedure TFrmRecurseDirTree.RecurseDirTree&#40;APath&#58; string; AList&#58; TStrings&#41;;
    var
    searchRec&#58; TSearchRec;
    thePath&#58; string;
    begin
    if &#40;Length&#40;thePath&#41; > 0&#41; then
    Exit;
    &#123;Riffle through the subdirectories and find the file&#40;s&#41; there&#125;
    thePath &#58;= APath;
    if &#40;thePath&#91;Length&#40;thePath&#41;&#93; &lt;> '\'&#41; then
    thePath &#58;= thePath + '\';
    if FindFirst&#40;thePath + '*.*', faDirectory, searchRec&#41; = 0 then
    try
    repeat
    if &#40;searchRec.Attr and faDirectory > 1&#41; and &#40;searchRec.Name &lt;> '.'&#41; and
    &#40;searchRec.Name &lt;> '..'&#41; then
    begin
    AList.Add&#40;thePath + searchRec.Name&#41;;
    RecurseDirTree&#40;thePath + searchRec.Name + '\', AList&#41;;
    Application.ProcessMessages;
    end;
    until
    FindNext&#40;searchRec&#41; &lt;> 0;
    finally
    SysUtils.FindClose&#40;searchRec&#41;;
    end;
    end;


    Solve 3&#58;

    Here is a procedure to scan for all bitmaps below the current directory and add them to a list. It can easily be modified to add all sub-directories to the list, just add "List.Add..." just before "ScanDirectory..." and delete the part that adds the bitmap filenames. Maybe it's better to change faAnyFile to faDirecory, but I am not sure if this will return all directories including hidden ones etc.

    procedure TForm1.ScanDirectory&#40;Path&#58; string; List&#58; TStringList; SubDirFlag&#58; Boolean&#41;;
    var
    SearchRec&#58; TSearchRec;
    Ext&#58; string;
    begin
    if Path&#91;Length&#40;Path&#41;&#93; &lt;> '\' then
    Path &#58;= Path + '\';
    if FindFirst&#40;Path + '*.*', faAnyFile, SearchRec&#41; = 0 then
    begin
    repeat
    if SearchRec.Attr = faDirectory then
    begin
    if SubDirFlag and &#40;SearchRec.Name &lt;> '.'&#41; and &#40;SearchRec.Name &lt;> '..'&#41; then
    ScanDirectory&#40;Path + SearchRec.Name, List, SubDirFlag&#41;;
    end
    else
    begin
    Ext &#58;= UpperCase&#40;ExtractFileExt&#40;SearchRec.Name&#4 1;&#41;;
    if &#40;Ext = '.BMP'&#41; then
    begin
    List.Add&#40;Path + SearchRec.Name&#41;;
    end;
    end;
    until
    FindNext&#40;SearchRec&#41; &lt;> 0;
    end;
    end;

    Use it as follows:
    ScanDirectory&#40;GetCurrentDir, YourStringList, False&#41;;

    Solve 4:
    procedure TForm1.Button1Click&#40;Sender&#58; TObject&#41;;
    var
    SearchRec&#58; TSearchRec;
    begin
    if FindFirst&#40;'c&#58;\images\*.jpg', faAnyFile, SearchRec&#41; = 0 then
    try
    repeat
    listbox1.items.add&#40;searchrec.name&#41;;
    until
    Findnext&#40;SearchRec&#41; &lt;> 0;
    finally
    FindClose&#40;SearchRec&#41;;
    end;
    end;

    Note: if you are displaying many items, you will probably want to wrap the code within listbox1.items.BeginUpdate/EndUpdate.

    Solve 5:
    Searching for a file in a directory:
    function FileExistsExt&#40;const aPath, aFilename&#58; string&#41;&#58; Boolean;
    var
    DSearchRec&#58; TSearchRec;
    begin
    Result &#58;= FileExists&#40;IncludeTrailingPathDelimiter&#40;aP ath&#41; + aFilename&#41;;
    if not Result then
    begin
    if FindFirst&#40;APath + '\*', faDirectory, DSearchRec&#41; = 0 then
    begin
    repeat
    if &#40;DSearchRec.Name &lt;> '.'&#41; and &#40;DSearchRec.Name &lt;> '..'&#41; then
    Result &#58;= FileExistsExt&#40;IncludeTrailingPathDelimiter&#40 ;aPath&#41; +
    DSearchRec.Name, aFilename&#41;;
    until
    FindNext&#40;DSearchRec&#41; &lt;> 0;
    end;
    FindClose&#40;DSearchRec&#41;;
    end;
    end;

    Usage:
    &#123; ... &#125;
    if FileExistsExt&#40;'C&#58;', 'Testfile.dat'&#41; then
    &#123; ... &#125;


    Solve 6:
    The following function receives as parameters a file specification (like for example 'C:\My Documents\*.xls' or 'C:\*' if you want to search the entire hard disk) and optionally a set of attributes (exactly as Delphi's FindFirst function), and it returs a StringList with the full pathnames of the found files. You should free the StringList after using it.
    interface

    function FindFile&#40;const filespec&#58; TFileName; attributes&#58; integer
    = faReadOnly or faHidden or faSysFile or faArchive&#41;&#58; TStringList;

    implementation

    function FindFile&#40;const filespec&#58; TFileName;
    attributes&#58; integer&#41;&#58; TStringList;
    var
    spec&#58; string;
    list&#58; TStringList;

    procedure RFindFile&#40;const folder&#58; TFileName&#41;;
    var
    SearchRec&#58; TSearchRec;
    begin
    // Locate all matching files in the current
    // folder and add their names to the list
    if FindFirst&#40;folder + spec, attributes, SearchRec&#41; = 0 then
    begin
    try
    repeat
    if &#40;SearchRec.Attr and faDirectory = 0&#41; or
    &#40;SearchRec.Name &lt;> '.'&#41; and &#40;SearchRec.Name &lt;> '..'&#41; then
    list.Add&#40;folder + SearchRec.Name&#41;;
    until FindNext&#40;SearchRec&#41; &lt;> 0;
    except
    FindClose&#40;SearchRec&#41;;
    raise;
    end;
    FindClose&#40;SearchRec&#41;;
    end;
    // Now search the subfolders
    if FindFirst&#40;folder + '*', attributes
    or faDirectory, SearchRec&#41; = 0 then
    begin
    try
    repeat
    if &#40;&#40;SearchRec.Attr and faDirectory&#41; &lt;> 0&#41; and
    &#40;SearchRec.Name &lt;> '.'&#41; and &#40;SearchRec.Name &lt;> '..'&#41; then
    RFindFile&#40;folder + SearchRec.Name + '\'&#41;;
    until FindNext&#40;SearchRec&#41; &lt;> 0;
    except
    FindClose&#40;SearchRec&#41;;
    raise;
    end;
    FindClose&#40;SearchRec&#41;;
    end;
    end; // procedure RFindFile inside of FindFile

    begin // function FindFile
    list &#58;= TStringList.Create;
    try
    spec &#58;= ExtractFileName&#40;filespec&#41;;
    RFindFile&#40;ExtractFilePath&#40;filespec&#41;&#4 1;;
    Result &#58;= list;
    except
    list.Free;
    raise;
    end;
    end;

    Sample call
    You can try this function placing a ListBox and a button on a form and adding this code to the OnClick event of the button:
    procedure TForm1.Button1Click&#40;Sender&#58; TObject&#41;;
    var
    list&#58; TStringList;
    begin
    list &#58;= FindFile&#40;'C&#58;\Delphi\*.pas'&#41;;
    ListBox1.Items.Assign&#40;list&#41;;
    list.Free;
    end;


    Solve 7:
    I thought if there was a way to create a function that does not recursively call itself to list all the files in the harddisk, so that there might be some improvement in speed, other than making the function more complex there were no speed improvements. Here is the code of the function any way.
    type
    PRecInfo = ^TRecInfo;
    Trecinfo = record
    prev&#58; PRecInfo;
    fpathname&#58; string;
    srchrec&#58; Tsearchrec;
    end;

    function TForm1.RecurseDirectory1&#40;fname&#58; string&#41;&#58; tstringlist;
    var
    f1, f2&#58; Tsearchrec;
    p1, tmp&#58; PRecInfo;
    fwc&#58; string;
    fpath&#58; string;
    fbroke1, fbroke2&#58; boolean;
    begin
    result &#58;= tstringlist.create;
    fpath &#58;= extractfilepath&#40;fname&#41;;
    fwc &#58;= extractfilename&#40;fname&#41;;
    new&#40;p1&#41;;
    p1.fpathname &#58;= fpath;
    p1.prev &#58;= nil;
    fbroke1 &#58;= false;
    fbroke2 &#58;= false;
    while &#40;p1 &lt;> nil&#41; do
    begin
    if &#40;fbroke1 = false&#41; then
    if &#40;fbroke2 = false&#41; then
    begin
    if &#40;findfirst&#40;fpath + '*', faAnyfile, f1&#41; &lt;> 0&#41; then
    break;
    end
    else if &#40;findnext&#40;f1&#41; &lt;> 0&#41; then
    begin
    repeat
    findclose&#40;f1&#41;;
    if &#40;p1 = nil&#41; then
    break;
    fpath &#58;= p1.fpathname;
    f1 &#58;= p1.srchrec;
    tmp &#58;= p1.prev;
    dispose&#40;p1&#41;;
    p1 &#58;= tmp;
    until &#40;findnext&#40;f1&#41; = 0&#41;;
    if &#40;p1 = nil&#41; then
    break;
    end;
    if &#40;&#40;f1.Name &lt;> '.'&#41; and &#40;f1.name &lt;> '..'&#41; and &#40;&#40;f1.Attr and fadirectory&#41; =
    fadirectory&#41;&#41; then
    begin
    fbroke1 &#58;= false;
    new&#40;tmp&#41;;
    with tmp^ do
    begin
    fpathname &#58;= fpath;
    srchrec.Time &#58;= f1.time;
    srchrec.Size &#58;= f1.size;
    srchrec.Attr &#58;= f1.attr;
    srchrec.Name &#58;= f1.name;
    srchrec.ExcludeAttr &#58;= f1.excludeattr;
    srchrec.FindHandle &#58;= f1.findhandle;
    srchrec.FindData &#58;= f1.FindData;
    end;
    tmp.prev &#58;= p1;
    p1 &#58;= tmp;
    fpath &#58;= p1.fpathname + f1.name + '\';
    if findfirst&#40;fpath + fwc, faAnyfile, f2&#41; = 0 then
    begin
    result.add&#40;fpath + f2.Name&#41;;
    while &#40;findnext&#40;f2&#41; = 0&#41; do
    result.add&#40;fpath + f2.Name&#41;;
    findclose&#40;f2&#41;;
    end;
    fbroke2 &#58;= false;
    end
    else
    begin
    if &#40;findnext&#40;f1&#41; &lt;> 0&#41; then
    begin
    findclose&#40;f1&#41;;
    fpath &#58;= p1.fpathname;
    f1 &#58;= p1.srchrec;
    fbroke1 &#58;= false;
    fbroke2 &#58;= true;
    tmp &#58;= p1.prev;
    dispose&#40;p1&#41;;
    p1 &#58;= tmp;
    end
    else
    begin
    fbroke1 &#58;= true;
    fbroke2 &#58;= false;
    end;
    end;
    end;
    fpath &#58;= extractfilepath&#40;fname&#41;;
    if findfirst&#40;fname, faAnyfile, f1&#41; = 0 then
    begin
    result.add&#40;fpath + f2.Name&#41;;
    while &#40;findnext&#40;f1&#41; = 0&#41; do
    result.add&#40;fpath + f2.Name&#41;;
    findclose&#40;f1&#41;;
    end;
    end;

    </div>

  3. #3
    کمپایلر می نویسید؟

  4. #4
    سلام
    متشکرم
    این کدها همه اش یکی هست دیگه؟
    درسته؟
    یعنی فرق نمی کند که از کدام یک استفاده کنم؟

    ممنون

  5. #5
    سلام
    متشکرم آقای کرامتی
    اما من کدی را می خواهم که با دادن اسم درایو تمام درایو را بگردد
    اما این کدها مخصوص یک پوشه است


    متشکرم

  6. #6
    سلام
    این برنامه را یاد من نیست از کدام سایت گرفتم
    فایل های ضمیمه فایل های ضمیمه

  7. #7
    کاربر دائمی آواتار Hamid_PaK
    تاریخ عضویت
    تیر 1384
    محل زندگی
    تهران
    پست
    1,125
    همه این کد درسته ولی اگر ترد نباشه یعنی ...

    یا حق ...

قوانین ایجاد تاپیک در تالار

  • شما نمی توانید تاپیک جدید ایجاد کنید
  • شما نمی توانید به تاپیک ها پاسخ دهید
  • شما نمی توانید ضمیمه ارسال کنید
  • شما نمی توانید پاسخ هایتان را ویرایش کنید
  •