2009-05-02 4 views

답변

4

디렉토리의 모든 파일을 읽으려고합니까? 이 클래스를 사용해보십시오. 이것은 내 원래 코드가 아니지만 조금 수정하고 사용자 정의했습니다. TFilestream에 전달할 수있는 문자열 목록에 설정된 기준과 일치하는 모든 파일 이름을 제공합니다.

unit findfile; 

interface 

uses 
    Classes; 

type 
    TFileAttrKind = (ffaReadOnly, ffaHidden, ffaSysFile, ffaDirectory, ffaArchive, ffaAnyFile); 
    TFileAttr = set of TFileAttrKind; 

    TFindFile = class(TObject) 
    private 
     s: TStringList; 

     fSubFolder : boolean; 
     fAttr: TFileAttr; 
     FPath : string; 
     FBasePath: string; 
     fFileMask : string; 
     FDepth: integer; 

     procedure SetPath(Value: string); 
     procedure FileSearch(const inPath : string); 
     function cull(value: string): string; 
    public 
     constructor Create(path: string); 
     destructor Destroy; override; 

     function SearchForFiles: TStringList; 

     property FileAttr: TFileAttr read fAttr write fAttr; 
     property InSubFolders : boolean read fSubFolder write fSubFolder; 
     property Path : string read fPath write SetPath; 
     property FileMask : string read fFileMask write fFileMask ; 
    end; 

implementation 

{$WARN SYMBOL_PLATFORM OFF} 
{$WARN UNIT_PLATFORM OFF} 
uses 
    Windows, SysUtils, FileCtrl; 

constructor TFindFile.Create(path: string); 
begin 
    inherited Create; 
    FPath := path; 
    FBasePath := path; 
    FileMask := '*.*'; 
    FileAttr := [ffaReadOnly, ffaDirectory, ffaArchive]; 
    s := TStringList.Create; 
    FDepth := -1; 
end; 

procedure TFindFile.SetPath(Value: string); 
begin 
    if fPath <> Value then 
    begin 
     if (Value <> '') and (DirectoryExists(Value)) then 
     fPath := IncludeTrailingPathDelimiter(Value); 
    end; 
end; 

function TFindFile.SearchForFiles: TStringList; 
begin 
    s.Clear; 
    try 
     FileSearch(Path); 
    finally 
     Result := s; 
    end; 
end; 

function TFindFile.cull(value: string): string; 
begin 
    result := StringReplace(value, FBasePath, '', []); 
end; 

destructor TFindFile.Destroy; 
begin 
    s.Free; 
    inherited Destroy; 
end; 

procedure TFindFile.FileSearch(const InPath : string); 
var Rec : TSearchRec; 
    Attr : integer; 
begin 
    inc(FDepth); 
    try 
     Attr := 0; 
     if ffaReadOnly in FileAttr then 
     Attr := Attr + faReadOnly; 
     if ffaHidden in FileAttr then 
     Attr := Attr + faHidden; 
     if ffaSysFile in FileAttr then 
     Attr := Attr + faSysFile; 
     if ffaDirectory in FileAttr then 
     Attr := Attr + faDirectory; 
     if ffaArchive in FileAttr then 
     Attr := Attr + faArchive; 
     if ffaAnyFile in FileAttr then 
     Attr := Attr + faAnyFile; 

     if SysUtils.FindFirst(inPath + FileMask, Attr, Rec) = 0 then 
     try 
      repeat 
       if (Rec.Name = '.') or (Rec.Name = '..') then 
        Continue; 
       s.Add(cull(inPath) + Rec.Name); 
      until SysUtils.FindNext(Rec) <> 0; 
     finally 
      SysUtils.FindClose(Rec); 
     end; 

     If not InSubFolders then 
     Exit; 

     if SysUtils.FindFirst(inPath + '*.*', faDirectory, Rec) = 0 then 
     try 
      repeat 
       if ((Rec.Attr and faDirectory) <> 0) and (Rec.Name <> '.') and (Rec.Name <> '..') then 
       begin 
        FileSearch(IncludeTrailingPathDelimiter(inPath + Rec.Name)); 
       end; 
      until SysUtils.FindNext(Rec) <> 0; 
     finally 
      SysUtils.FindClose(Rec); 
     end; 
    finally 
     dec(FDepth); 
    end; 
end; 

end. 
+0

감사합니다.하지만이 코드는 delphi 2007에서 작동합니다. –

+0

알고있는 한. –

+0

하지만 VCL 양식 응용 프로그램으로 사용하려합니다. –

1

동작을 반복하려면 루프이라고합니다. 델파이에는 루프에 대한 예약어가 3 개 있습니다 (for, repeatwhile). 모두는 도움말 파일에 문서화되어 있습니다. 가장 중요한 주제는 structured statements입니다. 당신은 그들에 대해 읽는 것이 좋을 것입니다.

기존의 for 루프는 처리하려는 배열이나 목록이있는 경우에 가장 적합합니다. 아마도 파일 이름 목록 일 것입니다.

for i := 0 to High(FileNames) do begin ... end; 

나이 :

for i := 0 to Pred(FileNames.Count) do begin ... end; 

는 그런 다음 현재 반복의 파일 이름을 얻기 위해 루프 내 FileNames[i]를 참조합니다 당신은이 같은 루프를 작성할 수 있습니다. 또한 파일 이름이 포함 된 것이 열거 자 또는 반복자을 사용할 때 사용할 새로운 스타일 for 루프가 있습니다.

for name in FileNames do begin ... end; 

Whilerepeat 루프는 루프가 코드를 실행해야하는 횟수를 시작하기 전에 반드시 모를 때 사용됩니다 그럼 당신은 이런 식으로 루프를 작성합니다. 이것을 FindFirstFindNext Delphi 함수와 함께 사용할 수 있습니다. 예 :

if FindFirst('*.txt', faAnyFile, SearchResult) = 0 then try 
    repeat 
    // Do something with SearchResult.Name 
    until FindNext(SearchResult) <> 0; 
finally 
    SysUtils.FindClose(SearchResult); 
end; 
관련 문제