Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Посик файлов


Автор: Rondo 17.1.2007, 05:55
Нашел такую процедуру, которая ищет в каталоге и подкаталогах нужные мне файлы
Код

procedure ScanDir(Dir: string);
var
  SearchRec: TSearchRec;
begin
  if Dir<>'' then
    if Dir[length(Dir)]<>'\' then
      Dir:=Dir+'\';
    if FindFirst(Dir+'*.*', faAnyFile, SearchRec)=0 then
      repeat
        if (SearchRec.name='.') or (SearchRec.name='..') then
          continue;
        if (SearchRec.Attr and faDirectory)<>0 then
          ScanDir(Dir+SearchRec.name)
        else begin
          if Pos('.ini', SearchRec.Name) <> 0 then
            IniPath := IniPath + Dir + SearchRec.Name + #13#10;
        end;
      until FindNext(SearchRec)<>0;
  FindClose(SearchRec);
end;


Работает как надо, только требует модуль SysUtils - лишний размер. Но мне этот модуль включать нельзя, сильно растет размер .exe файла .. Кто нибуть подкиньте аналог этой процедуры не использующая модуля SysUtils - размер критичен! Или можно чтонибудь подобное сделать в KOL? 

Автор: DoZENT 17.1.2007, 09:35
Пример из MSDN правда без рекурсии
Код

int main(int argc, char *argv[])
{
   WIN32_FIND_DATA FindFileData;
   HANDLE hFind = INVALID_HANDLE_VALUE;
   char DirSpec[MAX_PATH];  // directory specification
   DWORD dwError;

   printf ("Target directory is %s.\n", argv[1]);
   strncpy (DirSpec, argv[1], strlen(argv[1])+1);
   strncat (DirSpec, "\\*", 3);

   hFind = FindFirstFile(DirSpec, &FindFileData);

   if (hFind == INVALID_HANDLE_VALUE) 
   {
      printf ("Invalid file handle. Error is %u\n", GetLastError());
      return (-1);
   } 
   else 
   {
      printf ("First file name is %s\n", FindFileData.cFileName);
      while (FindNextFile(hFind, &FindFileData) != 0) 
      {
         printf ("Next file name is %s\n", FindFileData.cFileName);
      }
    
      dwError = GetLastError();
      FindClose(hFind);
      if (dwError != ERROR_NO_MORE_FILES) 
      {
         printf ("FindNextFile error. Error is %u\n", dwError);
         return (-1);
      }
   }
   return (0);
}

Автор: Rondo 17.1.2007, 11:13
В С++ ваще ниче не понимаю smile

Автор: Snowy 17.1.2007, 11:23
http://forum.vingrad.ru/index.php?showtopic=45659&view=findpost&p=352474

Автор: Alexeis 17.1.2007, 11:47
Код

procedure ScanDir(Dir: string);
var
  Find      : TWin32FindData;
  hFind     : THANDLE;

begin
  if Dir<>''
  then
    if Dir[length(Dir)]<>'\'
    then
      Dir:=Dir+'\';

  Dir := Dir + '*.*';
  hFind := windows.FindFirstFile(PChar(Dir), Find);
  if (hFind <> INVALID_HANDLE_VALUE)
  then
  Begin
    Repeat
      if ((Find.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) <> 0) and
         ((AnsiString(Find.cFileName) = '.') or (AnsiString(Find.cFileName) = '..'))
      then
        ScanDir(Dir+SearchRec.name)
      else
        //тут всякая обработка
        ;

    until not windows.FindNextFile(hFind, Find);

    windows.FindClose(hFind);
  end;

Автор: Snowy 17.1.2007, 11:51
"windows." можно не добавлять, т.к. SysUtils всё равно не подключен.

Автор: Alexeis 17.1.2007, 13:11
Snowy, уточнение никогда не вредно, кто знает, может в последствии кто-нибудь захочет использовать этот код вместе с VCL, а так получается что-то вроде универсального шаблончика. 
   ИМХО если не лень, то такие уточнения всегда на только пользу.

Автор: Rondo 17.1.2007, 16:04
Alexeis, Спасибо за код smile Только он выдает содержимое текущего каталога, мне еще нужно получить все что лежит в подкаталогах smile
И в 22 строке ошибка. Неизвестная переменная SearchRec.Name, заменил его этим Find.cFileName, но показывает только текущий каталог  smile 

Автор: Rondo 18.1.2007, 04:39
Тема еще актуальна, поиск не дает результатов  smile 

Вот нашел код, использующий KOL

Код

program Primer12;

uses
  Windows,
  Messages,
  Kol;

  {$APPTYPE CONSOLE}
var
  Form: Pcontrol;
  // ----- элементы интерфейса -----
  List: PControl;
  // -----------------------------
  FindHandle : THandle;
  FindData : TWin32FindData;
  b: boolean;
  s: string;
begin
  Applet := NewApplet( 'Список файлов' );
  form:=NewForm(Applet, 'Список файлов' ).SetSize(300, 400);
  form.CenterOnParent;
  List := NewListBox(form, []).SetAlign(caClient);

  // устанавливаем атрибуты файла 
  FindData.dwFileAttributes := FILE_ATTRIBUTE_NORMAL;
  // ищем первый файл в каталоге C:\
  FindHandle := FindFirstFile('C:\Program Files\*.*', FindData);
  // если все Ok, тогда продолжаем
  if FindHandle <> INVALID_HANDLE_VALUE then
  begin
     b := true;
     while b do
     begin
       s := FindData.cFileName;
       // всякие точки и двоеточия нам не нужны
       if (s<>'..') and (s<>'.') then
         List.Add(s);
       b := FindNextFile(FindHandle, FindData);
     end;
  end;
  FindClose(FindHandle);

  run(Applet);
end.


Тоже ищет только то что лежит в текущем каталоге, в данном случае выдает только папку Program Files  smile 

Автор: Rondo 18.1.2007, 10:25
Код показывает только содержимое текущего каталога.

Автор: Yanis 18.1.2007, 11:17
Вот, что в конце концов должно было получиться у тебя:
Код
procedure ScanDir(Dir: string; var sFiles: string);
var
  fnd: TWin32FindData;
  hFnd: DWORD;
begin
  if Dir <> '' then
    if Dir[length(Dir)] <> '\' then Dir := Dir + '\';

  hFnd := FindFirstFile(PChar(Dir + '*.*'), fnd);
  if hFnd <> INVALID_HANDLE_VALUE then
    repeat
      if (fnd.cFileName[0] = '.') or (AnsiString(fnd.cFileName) = '..') then
        Continue;

      if Boolean((fnd.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY)) then
        ScanDir(Dir + fnd.cFileName, sFiles)
      else
        sFiles := sFiles + fnd.cFileName + #13#10;

    until not FindNextFile(hFnd, fnd);

  sFiles := Copy(sFiles, 1, Length(sFiles) - 2);
  Windows.FindClose(hFnd);
end;


Использование:
Код
var
  sf: string;
begin
  sf := '';
  ScanDir('C:\TEMP', sf);
  ShowMessage(sf);
end;

Автор: Rondo 19.1.2007, 06:08
Yanis, Респект smile Все отлично работает!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)