Delphi:如何处理多个文件?

时间:2009-05-02 13:47:18

标签: delphi delphi-2007

在Delphi 2007中,如何创建一个程序来读取第一个文件,然后将其关闭以读取第二个文件,依此类推,直到最后一个文件?

3 个答案:

答案 0 :(得分: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.

答案 1 :(得分:1)

DIFileFinder可能是您想要的。

答案 2 :(得分:1)

如果您想重复某个操作,那么您想要的是一个循环。 Delphi带有三个用于循环的保留字:forrepeatwhile。所有都记录在帮助文件中;我认为最重要的主题是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;