Delphi: как обрабатывать несколько файлов? - PullRequest
1 голос
/ 02 мая 2009

В Delphi 2007 как я могу сделать программу для чтения первого файла, а затем закрыть его для чтения второго и так далее до последнего файла?

Ответы [ 3 ]

4 голосов
/ 02 мая 2009

Вы пытаетесь прочитать каждый файл в каталоге? Попробуйте этот класс. Это не мой оригинальный код, но я немного его изменил и настроил. Он выдаст вам все имена файлов, которые соответствуют критериям, заданным вами в списке строк, который вы можете передать 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 голос
/ 03 мая 2009

Если вы хотите повторить действие, то то, что вы хотите, называется loop . Delphi поставляется с тремя зарезервированными словами для циклов: for, repeat и while. Все они документированы в файле справки; Я думаю, что всеобъемлющая тема называется структурированные утверждения . Тебе лучше прочитать о них.

Традиционный цикл 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;
Циклы

While и repeat используются, когда вы не обязательно знаете до запуска цикла, сколько раз вам понадобится запустить код. Вы можете использовать это в сочетании с функциями FindFirst и FindNext Delphi. Например:

if FindFirst('*.txt', faAnyFile, SearchResult) = 0 then try
  repeat
    // Do something with SearchResult.Name
  until FindNext(SearchResult) <> 0;
finally
  SysUtils.FindClose(SearchResult);
end;
1 голос
/ 02 мая 2009

DIFileFinder может быть то, что вы хотели бы.

...