![]() |
![]() |
ddn |
![]() ![]()
Сообщение
#1
|
Группа: Пользователи Сообщений: 6 Пол: Мужской Репутация: ![]() ![]() ![]() |
Есть много вопросов по работе в 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 -------------------- взять бы всех программистов - да утопить
|
![]() ![]() |
ddn |
![]()
Сообщение
#2
|
Группа: Пользователи Сообщений: 6 Пол: Мужской Репутация: ![]() ![]() ![]() |
Цитата(volvo) Цитата(ddn) верно ли, что вызов FindNext(SR) возвращает в SR следующую запись (если она есть, если нет - SR неопределено или исходное значение?) в директории ее (исходной записи SR) расположения, а не в директории из последнего вызова процедуры FindFirst; Это что тут написано, можно объяснить? Какая директория последнего вызова FindFirst? Какая директория "ее (исходной записи SR) расположения"? Ты о чем вообще?FindFirst(Dir1+mask1, Attr1, SR1); (* Dir1 - директория расположения записи SR1 *) - 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); Директория расположения записи - это что? Запись располагается в памяти, если что... Терминология твоя ошибочна, задай вопросы с нормальной терминологией. И напиши, наконец, кусок кода, в котором у тебя получается не то поведение, которого ты ожидаешь... Не заставляй других угадывать, как это делал ты...---- прекращает ли вызов FindFirst(Dir2+mask2, Attr2, SR2) поиск в директории Dir1, сбрасывая его указатель ? (т.е. допустим только один поиск единовременно?); ----- прекращает ли аналогично вызов FindClose(SR1) поиск в директории Dir2, а вызов FindClose(SR2) поиск в директории Dir1 ?; Цитата(volvo) Ответ выделен: FindClose(SR) освобождает любые ресурсы ВСЕХ поисков ? (зачем параметр SR ?); или все-таки в последнего поиска вызванного FindFirst, или поиска соответствующего значению SR ?;Цитата((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. В хелпе 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);все равно выдает Error 89: ')' expected. (курсор на ':'), притом еще недавно на ту же самую программу выдавал что-то ... ':=' ... (курсор на '='). Ну как тут быть?! Странный отладчик и странный компилятор. Поэтому, я пока пытаюсь выяснить, как там в теории должно действовать (может я вообще неправильно что-то понимаю), чтобы не блуждать впотьмах, гадая, где там ошибка может быть. Цитата(volvo) То, чаво на белом свете, вообче не может быть! (по крайней мере - по твоему утверждению). Я видел этот пример. Хотя я стараюсь не использовать рекурсию, стараюсь сделать стек через file или array. Эта же рекурсия меня насторожила, она усилила мои подозрения, что допустим только один поиск единовременно.Цитата(volvo) {$TELEPATHY ON} Насчет проблемы с компиляцией - незнаю, а вот насчет проблем с пониманием работы FindFirst и FindNext - да. Да, я тоже тогда подумал про какие-то странные грязные трюки с глобальными переменными (в данном случае это параметры поиска). Если в внутри одной процедуры, то только один поиск единовременно - неявная глобальная переменная инициируемая FindFirst, то в разных вызовах - своя переменная поиска, локальная. Разве значение глобальной переменной не передается из тела процедуры внутрь всех процедурных вызовов в ней?P.P.S. Разницу между локальными и глобальными переменными хорошо понимаешь? Корень твоей проблемы - в этом... {$TELEPATHY OFF} Цитата(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 -------------------- взять бы всех программистов - да утопить
|
![]() ![]() |
![]() |
Текстовая версия | 18.07.2025 20:43 |