Masking files in delphi

I am trying to find all files with extenstion.cbr or .cbz

Should I set the mask to * .cb?

it finds * .cbproj files. How to configure a mask only for the presence of .cbr and .cbz files?

here is the code i am using.

I have two edit fields. EDIT1 is the place to search, EDIT2 is the place where I put my mask. A list to show what he found, and a search button.

edit1 := c:\ edit2 := mask (*.cb?) 

space

  procedure TFAutoSearch.FileSearch(const PathName, FileName : string; const InDir : boolean); var Rec : TSearchRec; Path : string; begin Path := IncludeTrailingBackslash(PathName); if FindFirst(Path + FileName, faAnyFile - faDirectory, Rec) = 0 then try repeat ListBox1.Items.Add(Path + Rec.Name); until FindNext(Rec) <> 0; finally FindClose(Rec); end; If not InDir then Exit; if FindFirst(Path + '*.*', faDirectory, Rec) = 0 then try repeat if ((Rec.Attr and faDirectory) <> 0) and (Rec.Name<>'.') and (Rec.Name<>'..') then FileSearch(Path + Rec.Name, FileName, True); until FindNext(Rec) <> 0; finally FindClose(Rec); end; end; //procedure FileSearch procedure TFAutoSearch.Button1Click(Sender: TObject); begin FileSearch(Edit1.Text, Edit2.Text, CheckBox1.State in [cbChecked]); end; end. 
+4
source share
2 answers

The easiest way is to use ExtractFileExt for the current file name and check if it matches any of your desired extensions.

Here is a completely rewritten version of your FileSearch routine that does exactly what you are trying to do (depending on your question, anyway):

 procedure TFAutoSearch.FileSearch(const ARoot: String); var LExt, LRoot: String; LRec: TSearchRec; begin LRoot := IncludeTrailingPathDelimiter(ARoot); if FindFirst(LRoot + '*.*', faAnyFile, LRec) = 0 then begin try repeat if (LRec.Attr and faDirectory <> 0) and (LRec.Name <> '.') and (LRec.Name <> '..') then FileSearch(LRoot + LRec.Name) else begin LExt := UpperCase(ExtractFileExt(LRoot + LRec.Name)); if (LExt = '.CBR') or (LExt = '.CBZ') then ListBox1.Items.Add(LRoot + LRec.Name); end; until (FindNext(LRec) <> 0); finally FindClose(LRec); end; end; end; 

While another answer, involving the use of several extensions as a *.cbr;*.cbz , should (in principle, in any case) work, I was proud to note that the FindFirst and FindNext in Delphi are generally not accept several masked extensions!

The code I provided you should work great for your needs, so enjoy!

UPDATED : allow the use of multiple extensions in the mask dynamically at runtime (as indicated in the first comment on this answer).

What we need to do is take a String from your TEdit control (this is String β€” this is one or more file extensions, as you would expect), β€œExplode” String in Array and map each file to each extension in Array .

Sounds harder than it is:

 type TStringArray = Array of String; // String Dynamic Array type... // Now let provide a "Mask Container" inside the containing class... TFAutoSearch = class(TForm) // Normal stuff in here private FMask: TStringArray; // Our "Mask Container" end; 

This code fills FMask each individual mask extension, separated by a character ; e.g. .CBR;.CBZ .

Note that this method will not accept wildcards or any other Regex magic, but you can change it as you wish!

 procedure TFAutoSearch.ExplodeMask(const AValue: String); var LTempVal: String; I, LPos: Integer; begin LTempVal := AValue; I := 0; while Length(LTempVal) > 0 do begin Inc(I); SetLength(FMask, I); LPos := Pos(';', LTempVal); if (LPos > 0) then begin FMask[I - 1] := UpperCase(Copy(LTempVal, 0, LPos - 1)); LTempVal := Copy(LTempVal, LPos + 1, Length(LTempVal)); end else begin FMask[I - 1] := UpperCase(LTempVal); LTempVal := EmptyStr; end; end; end; 

Now we need a function to determine if the assigned file matches any of the defined extensions:

 function TFAutoSearch.MatchMask(const AFileName: String): Boolean; var I: Integer; LExt: String; begin Result := False; LExt := UpperCase(ExtractFileExt(LExt)); for I := Low(FMask) to High(FMask) do if (LExt = FMask[I]) then begin Result := True; Break; end; end; 

Now the FileSearch procedure has been changed here:

 procedure TFAutoSearch.FileSearch(const ARoot: String); var LRoot: String; LRec: TSearchRec; begin LRoot := IncludeTrailingPathDelimiter(ARoot); if FindFirst(LRoot + '*.*', faAnyFile, LRec) = 0 then begin try repeat if (LRec.Attr and faDirectory <> 0) and (LRec.Name <> '.') and (LRec.Name <> '..') then FileSearch(LRoot + LRec.Name) else begin if (MatchMask(LRoot + LRec.Name)) then ListBox1.Items.Add(LRoot + LRec.Name); end; until (FindNext(LRec) <> 0); finally FindClose(LRec); end; end; end; 

Finally, here's how you start your search:

 procedure TFAutoSearch.btnSearchClick(Sender: TObject); begin ExplodeMask(edMask.Text); FileSearch(edPath.Text); end; 

Where edMask defined as Edit2 in your question and edPath is defined as Edit1 in your question. Just remember that this method does not support the use of wildcards or other special characters, so edMask.Text should be something like .CBR;.CBZ

If you use the Regex library for Delphi, you can easily change this method to support all the expression cases you could ever imagine!

+7
source

The Dorean proposal to replace the *.cbr;*.cbz should work. That is, it will no longer match cbproj. However, it will still match cbzy or any other extension that starts with cbr or cbz. The reason for this is that FindFirst / FindNext matches both the long form and the old short forms (8.3) of file names. Thus, short forms will always have truncated extensions, where cbproj is shortened to cbp and therefore corresponds to cb ?.

This can be avoided by using FindFirstEx instead, but this requires a little reworking of your search function and actually doesn't work for me. So instead, I just double-checked all matches using the MatchesMask function.

+3
source

Source: https://habr.com/ru/post/1436577/


All Articles