IPB
ЛогинПароль:

> проблемы работы с директориями
ddn
сообщение 13.07.2010 9:12
Сообщение #1





Группа: Пользователи
Сообщений: 6
Пол: Мужской

Репутация: -  0  +


Есть много вопросов по работе в BP7, TMT (3.90), FPC (2.4.0.i386-win32) под WinXP:
1) верно ли, процедуры FindFirst и FindNext могут одновременно работать с несколькими директориями и даже с одной директорией через несколько указателей;
2) верно ли, что указатель поиска в директории определяется только записью файла SR (тип TSearchRec), но не директорией в которой она расположена, т.е. только по записи файла SR возможно непосредственно определить ее директорию и ее расположение в директории;
3) верно ли, что вызов FindNext(SR) возвращает в SR следующую запись (если она есть, если нет - SR неопределено или исходное значение?) в директории ее (исходной записи SR) расположения, а не в директории из последнего вызова процедуры FindFirst;
4) верно ли, что вызов FindClose(SR) прекращает поиск (работу с указателем) в директории расположения записи, а не в директории из последнего вызова процедуры FindFirst, поиск в других директориях не прекращается (непонятно, зачем вообще нужна эта процедура, если вся работа идет с данными из записи SR);
- без выполнения данных взаимосвязанных утверждений рекурсивный поиск в директориях НЕВОЗМОЖЕН (по крайней мере, без создания списков их содержимого),

далее:
5) верно ли, что путь к директории в вызове процедуры FindFirst должен заканчиваться разделителем '\';
6) возможна ли проверка существования файла, директории или лог. диска по его имени/полному_имени без использования процедур FindFirst и FindNext;
7) возможна ли работа с текущей директорией (получение абс. пути, изменение);
8) верно ли, что имена директорий SR.name в их записях SR из их наддиректорий не содержат разделителя '\';
9) верно ли, что записи в любой не изменившейся директории при каждой ее обработке процедурами FindFirst и FindNext выдаются в одном и том же порядке (лексикографическом по именам?);
10) как обеспечить работу с длинными именами файлов (как вызвать Win под FPC);
11) верно ли, что поле Time в TSearchRec - это время создания файла (если нет, как узнать/изменить время создания), или это время его последнего изменения/открытия;
12) что представляют собой неизвестные компилятору типы полей записи SR файла в директории под Win: TFileName (=string ?), THandle, TWin32FindData, каким характеристикам файла они и Fill (тип array[1..21] of Byte) отвечают;
Win32 target
type
TSearchRec = record
Fill : array[1..21] of Byte;
Attr : Byte;
Time : Longint;
Size : Longint;
Name : TFileName;
ExcludeAttr : Longint;
FindHandle : THandle;
FindData : TWin32FindData
end;


--------------------
взять бы всех программистов - да утопить
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
 
 Ответить  Открыть новую тему 
Ответов
ddn
сообщение 13.07.2010 12:58
Сообщение #2





Группа: Пользователи
Сообщений: 6
Пол: Мужской

Репутация: -  0  +


Цитата(volvo)
Цитата(ddn)
верно ли, что вызов FindNext(SR) возвращает в SR следующую запись (если она есть, если нет - SR неопределено или исходное значение?) в директории ее (исходной записи SR) расположения, а не в директории из последнего вызова процедуры FindFirst;
Это что тут написано, можно объяснить? Какая директория последнего вызова FindFirst? Какая директория "ее (исходной записи SR) расположения"? Ты о чем вообще?
(Dir1<>Dir2)
FindFirst(Dir1+mask1, Attr1, SR1); (* Dir1 - директория расположения записи SR1 *)
FindFirst(Dir2+mask2, Attr2, SR2); (* Dir2 - директория расположения записи SR2 и директория последнего вызова FindFirst *)
FindNext(SR1);
FindClose(SR1) либо FindClose(SR2);

- FindNext(SR1) ищет следующую запись в директории Dir1 расположения записи SR1 или ищет в последней вызванной FindFirst директории Dir2 игнорируя значение SR1 ?; нужно ли вообще значение SR1 для поиска, или только для присвоения результата ?;
-- ...присваивая следующую запись значению SR1, если она найдена, каковым делает значение SR1, если она не найдена: делает неопределенным, оставляет прежнее (возможно непроинициированное), каким угодно (в т.ч. ошибочным) ?;
--- можно ли из значения SR получить указатель поиска в директории, используется ли это в FindNext(SR) ?; а получить маску и атрибуты поиска, и вообще отнести SR по ее имени к конкретному вызову поиска FindFirst(Dir+mask, Attr, SR) ? (ведь значение SR мы можем присвоить другой переменной SR0 и работать уже с ней: FindNext(SR0), FindClose(SR0) - как мы (т.е. программа) определим по имени SR0 к какому вызову поиска она относится? если поисков допускается несколько одновременно - разве что по значению SR0);
Быть может следует говорить не о директории поиска, а о самом поиске, с конкретными параметрами: директория, маска имени файла, атрибуты (привязан он к конкретному имени SR, или определяется через значение SR - неясно);

Цитата(volvo)
Цитата(ddn)
верно ли, что вызов FindClose(SR) прекращает поиск (работу с указателем) в директории расположения записи, а не в директории из последнего вызова процедуры FindFirst, поиск в других директориях не прекращается (непонятно, зачем вообще нужна эта процедура, если вся работа идет с данными из записи SR);
Директория расположения записи - это что? Запись располагается в памяти, если что... Терминология твоя ошибочна, задай вопросы с нормальной терминологией. И напиши, наконец, кусок кода, в котором у тебя получается не то поведение, которого ты ожидаешь... Не заставляй других угадывать, как это делал ты...
Директория расположения записи файла SR - это директория, откуда она была прочитана процедурой FindFirst или FindNext (где расположен отвечающий SR файл);
---- прекращает ли вызов FindFirst(Dir2+mask2, Attr2, SR2) поиск в директории Dir1, сбрасывая его указатель ? (т.е. допустим только один поиск единовременно?);
----- прекращает ли аналогично вызов FindClose(SR1) поиск в директории Dir2, а вызов FindClose(SR2) поиск в директории Dir1 ?;

Цитата(volvo)
Ответ выделен:
Цитата((rtl.pdf стр 299))
FindClose frees any resources associated with the search record F.
This call is needed to free any internal resources allocated by the FindFirst or FindNext calls.
FindClose(SR) освобождает любые ресурсы ВСЕХ поисков ? (зачем параметр SR ?); или все-таки в последнего поиска вызванного FindFirst, или поиска соответствующего значению SR ?;
В хелпе TMT ее нет, а у FPC вообще нет хелпа. Где-то на форуме видел пример с FindClose.

Цитата(volvo)
Цитата("ddn")
что представляют собой неизвестные компилятору типы полей записи SR файла в директории под Win
Компилятору все прекрасно известно. Повторяю: эти функции используются не первый год, если что-то неизвестно - ошибку ищи у себя в коде, значит, неверно вызываешь... Телепаты с форума ушли...
Я имел в виду, что в хелпе их нет.
Что до ошибки, то пока до этого дело не дошло. У меня написана программка, но отладчика нет, а почему не компилируется (TMT, FPC): может синтаксическая мелочь какая, а может и тип неизвестен (ведь TSearchRec еще правильно вызвать нужно) - непонятно.
Вот на BP7 есть отладчик, но какой! Вот он писал, что тип TSearchRec неизвестен - ладно, описал его явно (в Dos-варианте), функции max и min тоже неизвестны - их можно смоделировать; uses Dos - Error 15: File not found (DOS.TPW). - ладно, обойдемся; но дальше он даже простые вещи перестал принимать, и я сделал совсем простую программу!
program cd (dir1, dir2: string);
begin
dir1=dir2
end.
все равно выдает Error 89: ')' expected. (курсор на ':'), притом еще недавно на ту же самую программу выдавал что-то ... ':=' ... (курсор на '='). Ну как тут быть?!
Странный отладчик и странный компилятор.
Поэтому, я пока пытаюсь выяснить, как там в теории должно действовать (может я вообще неправильно что-то понимаю), чтобы не блуждать впотьмах, гадая, где там ошибка может быть.

Цитата(volvo)
То, чаво на белом свете, вообче не может быть! (по крайней мере - по твоему утверждению).
Я видел этот пример. Хотя я стараюсь не использовать рекурсию, стараюсь сделать стек через file или array. Эта же рекурсия меня насторожила, она усилила мои подозрения, что допустим только один поиск единовременно.
Цитата(volvo)
{$TELEPATHY ON}
P.P.S. Разницу между локальными и глобальными переменными хорошо понимаешь? Корень твоей проблемы - в этом...
{$TELEPATHY OFF}
Насчет проблемы с компиляцией - незнаю, а вот насчет проблем с пониманием работы FindFirst и FindNext - да. Да, я тоже тогда подумал про какие-то странные грязные трюки с глобальными переменными (в данном случае это параметры поиска). Если в внутри одной процедуры, то только один поиск единовременно - неявная глобальная переменная инициируемая FindFirst, то в разных вызовах - своя переменная поиска, локальная. Разве значение глобальной переменной не передается из тела процедуры внутрь всех процедурных вызовов в ней?

Цитата(volvo)
Цитата(ddn)
без выполнения данных взаимосвязанных утверждений рекурсивный поиск в директориях НЕВОЗМОЖЕН (по крайней мере, без создания списков их содержимого)
А мужики-то не знают, и уже десятки лет используют рекурсивный поиск в папках/подпапках... Если ты чего-то не осилил, не надо говорить, что это невозможно... В общем, пример, как пытался - в студию... Больше я догадываться не собираюсь... Будет код - будет разговор.
Я имел ввиду, что невозможен, если допустим только один поиск единовременно.
С компилятором Паскаля я только начинаю работать. До этого я программировал в Мапле - исполняемая среда символьных вычислений, эрзац Паскаля/Модулы без статической типизации. Но работа с файлами неустраивала меня, слишком невнятно сделана. Мне требуется ясная работа с файлами и без ограничений.

Что до программки, которую я пишу.
Возникла потребность написать (на BP7, TMT, FPC под WinXP) процедуру для селективного копирования файлов и директорий (в том числе из вложенных директорий) из одной исходной директории в другую; структура директорий, а также атрибуты, имена, времена создания файлов и директорий сохраняются (содержимое файлов конечно тоже); селекция идет по атрибутам, имени, размеру, времени создания файла или директории.
Хотелось бы узнать, что там может быть некорректно.
Код
(* под файлами понимаются в том числе и директории *)
(*
глубина директорий c полными путями dir1 и dir2 принимается равной 0;
глубина директории = глубина расположения содержимых ею файлов, в том числе поддиректорий;
глубина директории на единицу больше глубины содержащей ее директории (наддиректории), т.е. на единицу больше глубины ее собственного расположения;
текущие директории - директории, обрабатываемые процедурами findfirst и findnext;
*)
procedure
  fullcopydir(
    dir1, dir2 : string; (* полные пути к существующим и не вложенным одна в другую директориям (т.е. пути вида '<LetterLogDisk>:\ ... \'), полное содержимое которых соответственно копируется и является результатом копирования *)
    prov : boolean; (* флаг необходимости проверки путей dir1 и dir2 на невложенность *)
    sel : function(
      attr : byte;
      time : longint;
      size : longint;
      name : string (* string[12] *)
    ) : boolean (* функция селекции на копирование для вложенных файлов, по некоторым полям их записи; поддиректории '.' и '..' игнорируются *)
  );
const
  maxh = 127; (* предел глубины расположения файлов *)
type
  t = record
    b : boolean; (* флаги обнаружения требуемых селекцией файлов в текущих вложенных директориях, либо требуемости самих этих директорий  *)
    ln : byte; (* длины полных путей к текущим вложенным директориям *)
    dir : string; (* относительные (от dir1) пути к текущим вложенным директориям *)
    sr : tsearchrec (* записи (в их наддиректориах) текущих вложенных директорий *)
  end;
var
  e : boolean;
  i : byte;
  c : t;
  f, d : file;
  h : 0..maxh; (* глубина расположения непосредственно обрабатываемого файла *)
  b : boolean; (* флаг обнаружения требуемых файлов в директории расположения непосредственно обрабатываемого файла *)
  ln : byte; (* длина полного пути к директории расположения непосредственно обрабатываемого файла *)
  sr : tsearchrec; (* запись непосредственно обрабатываемого файла в директории его расположения *)
  r : file of t;
begin
  if prov then
    begin
      ln := min(length(dir1), length(dir2));
      i := 1;
      while i<=ln and dir1[i]=dir2[i] do
        i := i+1;
      if i>ln then
        halt('исходные директории вложены')
    end;
  h := 0;
  b := true;
  ln := max(length(dir1), length(dir2));
  dir := dir1;
  e := findfirst(dir1+'*', anyfile, sr)=0;
  reset(r);
  while e do
    begin
      if (sr.attr and directory)=directory then (* запись файла отвечает директории *)
        if (sr.name='.') or (sr.name='..') then
          e := findnext(sr)=0;
        else (* приращение глубины, переход поиска в поддиректорию, создание ее копии без содержимого *)
          begin
            c.b := b;
            c.ln := ln;
            c.dir := dir;
            c.sr := sr;
            write(r, c);
            h := h+1;
            b := sel(sr.attr, sr.time, sr.size, sr.name);
            ln := ln+length(sr.name)+1;
            dir := dir+sr.name+'\';
            createdir(dir2+dir);
            assign(g, dir2+dir);
            setftime(g, sr.time);
            setfattr(g, sr.attr);
            e := findfirst(dir1+dir+'*', anyfile, sr)=0
          end
      else (* запись файла не отвечает директории *)
        begin
          if sel(sr.attr, sr.time, sr.size, sr.name) then (* копирование файла *)
            begin
              b := true;
              assign(f, dir1+dir+sr.name);
              assign(g, dir2+dir+sr.name);
              reset(f, 1);
              rewrite(g, 1);
                while not eof(f) do
                  begin
                    read(f, i);
                    write(g, i)
                  end;
              close(f);
              close(g);
              setftime(g, sr.time);
              setfattr(g, sr.attr)
            end;
          e := findnext(sr)=0 (* поиск следующей записи *)
        end;
      while (not e) and h>0 do (* возвращения из директорий до первой, где продолжение поиска результативно, либо достигнута исходная директория *)
        begin
          h := h-1;
          seek(r, h);
          read(r, c);
          seek(r, h);
          if not b then (* удаление скопированых пустых (без скопированных требуемых селекцией файлов) нетребуемых директорий  *)
            begin
              b := c.b;
              assign(g, dir2+dir);
              erase(g)
            end;
          ln := c.ln;
          dir := c.dir;
          findclose(sr);
          sr := c.sr;
          e := findnext(sr)=0
        end
    end;
  close(r)
end.


Сообщение отредактировано: ddn - 13.07.2010 18:23


--------------------
взять бы всех программистов - да утопить
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

Сообщений в этой теме
ddn   проблемы работы с директориями   13.07.2010 9:12
volvo   Ты для начала переведи то, что написано выше на но...   13.07.2010 9:46
ddn   (Dir1<>Dir2) FindFirst(Dir1+mask1, Attr1, SR...   13.07.2010 12:58
TarasBer   > (* Dir1 - директория расположения записи SR1 ...   13.07.2010 14:59
ddn   > (* Dir1 - директория расположения записи SR1 ...   13.07.2010 18:11
volvo   Если не работает - значит не должна. То, что должн...   13.07.2010 18:57
ddn   Я уже озвучил: селективное копирование файлов (в т...   13.07.2010 21:20
TarasBer   Ну может ручная развёртка хвостовой рекурсии и при...   14.07.2010 10:28
volvo   Ну да, процессор, ОС, все что угодно. Компилятор у...   14.07.2010 11:14
ddn   В общем случае. Рекурсия не только для вложенных п...   15.07.2010 10:02
Client   program fullcopydir( ...а указать имя программы?   15.07.2010 10:25
volvo   Если ты пишешь так, что у тебя получается результи...   15.07.2010 10:58
TarasBer   > В общем случае. Рекурсия не только для вложен...   15.07.2010 11:21
TarasBer   {$I+, Q+, R+, S+} program fullcopydir...   15.07.2010 11:59
Гость   а указать имя программы? fullcopydir и есть ее имя...   15.07.2010 13:31
volvo   В общем, так, ddn... [code=pas]{$mode delph...   15.07.2010 12:43
TarasBer   До меня дошло. program fullcopydir( dir1,...   15.07.2010 13:20
volvo   В таком случае ЭТО - не Паскаль. По крайней мере, ...   15.07.2010 13:36
TarasBer   > На Дельфи пока рано переходить, весит больше,...   15.07.2010 13:38
ddn   Вот блин, под гостем оставил. Там нужно исправить ...   15.07.2010 20:15
TarasBer   > Зачем SizeOf(Buf) вычисляется каждый раз, раз...   16.07.2010 9:12
volvo   Как угодно можно. Количество блоков Var/Type/Const...   16.07.2010 10:08


 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 



- Текстовая версия 18.07.2025 20:43
Хостинг предоставлен компанией "Веб Сервис Центр" при поддержке компании "ДокЛаб"