【问题标题】:Delphi: How to process multiple files?Delphi:如何处理多个文件?
【发布时间】:2009-05-02 13:47:17
【问题描述】:

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

【问题讨论】:

    标签: delphi delphi-2007


    【解决方案1】:

    您是否尝试读取目录中的每个文件?试试这门课。这不是我的原始代码,但我已经对其进行了一些修改和定制。它会为您提供与您在可以传递给 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.
    

    【讨论】:

    • 但我希望它作为 VCL 表单应用程序
    • 此代码适用于 VCL 表单应用程序。将其放在一个单独的单元中,然后“使用”该单元。您的主线程(管理 GUI)将处理事物的显示方式。 Mason 的代码可帮助您管理文件。最好将这些功能分开。
    • 对。此代码用于获取文件列表。一旦你有了它,就很容易使用 TFileStream 和 for 循环依次打开每个文件并对它们做任何你想做的事情。如果您提供一些关于您想要做什么的更具体的信息(最好在单独的问题中),我们可以给您一些更具体和有用的答案。
    【解决方案2】:

    DIFileFinder 可能是您想要的。

    【讨论】:

      【解决方案3】:

      如果你想重复一个动作,那么你想要的就是一个循环。 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] 以获取当前迭代的文件名。当包含您的文件名的事物具有可用的 enumeratoriterator 时,您还可以使用新样式的 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;
      

      【讨论】:

        猜你喜欢
        • 2014-11-22
        • 1970-01-01
        • 2021-08-14
        • 1970-01-01
        • 2010-11-26
        • 1970-01-01
        • 2013-09-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多