Текущий архив: 2004.01.16;
Скачать: CL | DM;
Вниз
считывание Найти похожие ветки
← →
selena (2004-01-06 07:07) [0]здраствуйте
Пишу такой текст вроде чего то находит и даже то что нужно,но при попытке считавыния выдает ошибку cannot open file c:\watcher\Vulnerable.txt что это такое?
var k,s,d:string;
r:integer;
dirinfo,t,rist: TSearchRec;
f:textfile;
begin
r := FindFirst("c:\watcher\*.*", FaDirectory, DirInfo);
repeat
chdir("c:\watcher");
begin
Application.ProcessMessages;
if ((DirInfo.Attr and FaDirectory = FaDirectory) and (DirInfo.Name <> ".") and (DirInfo.Name <> "..")) then
RichEdit1.Lines.Add(DirInfo.Name);
ChDir("c:\watcher\"+DirInfo.Name);
//считываю
begin
if FindFirst( "c:\watcher\"+DirInfo.Name+"\*.txt", faAnyFile AND nOT fADirectory, Rist ) = 0 then begin
RichEdit1.Lines.LoadFromFile("c:\watcher\"+ Rist.Name );
end;
end;
end;
until FindNext(dirinfo) <>0;
← →
goga (2004-01-06 07:18) [1]Забыл FindClose. А зачем ты делаешь "c:\watcher\"+ Rist.Name, если перед этим chdir? Попробуй без пути.
← →
Zergling © (2004-01-06 07:31) [2]Очевидно файл уже открыт благодаря FindFirst. Сначала занеси найденные файлы в некий массив или TStringList. А после завершения поиска, считывай файлы по именам из массива. В FAQ поищи процедуру поиска файлов. Она там оформлена более грамотно и без ошибок.
← →
selena (2004-01-06 07:54) [3]а где ставить findclose? В FAQ не нащел процедуру.
← →
Zergling © (2004-01-06 08:04) [4]>> Очевидно файл уже открыт благодаря FindFirst.
Этому неверить, неправда!!!
Всеработет нормально. Возможно ты запутался в переменных (dirinfo,t,rist: TSearchRec;)!
RichEdit1.Lines.LoadFromFile("c:\watcher\"+ Rist.Name );
на
RichEdit1.Lines.LoadFromFile("c:\watcher\"+ dirinfo.Name );
function AddSlashDir(Dir: String): String;
begin
if Dir[Length(Dir)]<> "\" then
Result := Dir+"\"
else
Result := Dir;
end;
Procedure FindFilesInDir(Path, FileMask: String; SearchSubDir:Boolean);
{ Ищет файл по маске в каталоге и его подкаталогах}
var
FSearchRec, DSearchRec: TSearchRec;
FindResult: integer;
function IsDirNotation(ADirName: String): Boolean;
begin
Result := (ADirName = ".") or (ADirName = "..");
end;
begin
AddSlashDir(Path);
{ Находится первое вхождение заданного файла }
FindResult := FindFirst(Path+FileMask,faAnyFile+faHidden+
faSysFile+faReadOnly,FSearchRec);
try
{ Поиск файлов в текущем каталоге и если файл найден, то добавляем в список}
while FindResult = 0 do
begin
FindResult := FindNext(FSearchRec);
Form1.RichEdit1.Lines.LoadFromFile(Path + FSearchRec.Name);
end;
// Поиск файлов в подкаталогах
if SearchSubDir then
Begin
{ А теперь просматриваются подкаталоги текущего каталога }
FindResult := FindFirst(Path+"*.*", faDirectory, DSearchRec);
{ Поиск файлов пока не просмотрены все каталоги}
while FindResult = 0 do
begin
if ((DSearchRec.Attr and faDirectory) = faDirectory) and
not IsDirNotation(DSearchRec.Name) then
// Рекурсия (проседура вызывает саму себя для поиска файлов в каталоге)
FindFilesInDir(Path+DSearchRec.Name,FileMask,SearchSubDir);
FindResult := FindNext(DSearchRec);
end;
End;
finally
FindClose(FSearchRec);
end;
end;
← →
NAlexey © (2004-01-06 08:30) [5]>Zergling ©
А почему не рекурсивно? И почему бы для этих целей не использовать API, все быстрее будет.
← →
Zergling © (2004-01-06 08:37) [6]NAlexey © (06.01.04 08:30) [5]
>> А почему не рекурсивно?
Непонял???
← →
NAlexey © (2004-01-06 08:39) [7]>Zergling ©
Ну на сколько я понял, сначала сканируются файлы текущего каталога, затем уже сканируются папки. У меня соответственно возник вопрос, почему не сразу рекурсивно? Извиняюсь конечно если чего не так понял.
← →
Zergling © (2004-01-06 08:51) [8]NAlexey © (06.01.04 08:39) [7]
А какая разница где сначала искать?
Всеравно нужно сканировать как текущий, так и вложенные каталоги (если требуется) - смысл?
>> И почему бы для этих целей не использовать API
Тоже ???
← →
NAlexey © (2004-01-06 08:54) [9]>А какая разница где сначала искать?
Ну не скажи, разница есть, и чем больше файлов и каталогов в текущем тем больше разница.
>Тоже ???
Что тоже?
← →
Zergling © (2004-01-06 09:19) [10]NAlexey © (06.01.04 08:54) [9]
>Тоже ???
Что тоже?
Намек на WinAPI твой неясен. Использутся функции не относящиеся к WinAPI?
>> Ну не скажи, разница есть, и чем больше файлов и каталогов в текущем тем больше разница.
Поясни РАЗНИЦУ! Искать, то тебе всеравно во всех каталогах (при поиске во вложенных каталогах) независимо от каличества файлов и папок. При поиске в одном каталоге, поиск идет только в нем, вложенные каталоги незатрагиваются!
>> чем больше файлов и каталогов
Разница во времени? Естественно предется перебрать все файлы, дабы узнать соответсвует ли имя файла заданному имени в критери поиска. И рекурсия тут совершенно непричем.
P.S. Может я чего недогоняю? Жду пояснений.
← →
NAlexey © (2004-01-06 09:42) [11]Хм... Хорошо, давай по порядку.
>Намек на WinAPI?
Да, намек на WinAPI. FindFirst, FindNext, FindClose маскируют API шные ф-ции: FindFirstFile, FindNextFile и FindClose. Я считаю что если воспользоваться ими то получится быстрее. Хотя подтвердить это может только эксперемент. Так же как и спорный вопрос о том что по времени будет одинаково что просканировать сначала файлы в каталоге а потом папки. Ну чтож, если интересно можно провести и эксперемент, например так:
{
RX
}
function NormalDir(const DirName: string): string;
begin
Result := DirName;
if (Result <> "") and
not (Result[Length(Result)] in [":", "\"])
then begin
if (Length(Result) = 1) and (UpCase(Result[1]) in ["A".."Z"]) then
Result := Result + ":\"
else
Result := Result + "\";
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
t1, t2, Fr: Int64;
procedure ScanDirs(const Path: string; IncludeSub: boolean);
var
SearchHandle: THandle;
FindData: TWin32FindData;
FName: string;
begin
SearchHandle := FindFirstFile(PChar(NormalDir(Path) + "*.*"), FindData);
if SearchHandle <> INVALID_HANDLE_VALUE then
try
repeat
FName := StrPas(FindData.cFileName);
if (FName <> ".") and (FName <> "..") then
if (FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY <> 0) then
begin
if IncludeSub then
ScanDirs(NormalDir(Path) + FName, IncludeSub);
end else
Memo1.Lines.Add(FName);
until not FindNextFile(SearchHandle, FindData);
finally
Windows.FindClose(SearchHandle);
end;
end;
begin
QueryPerformanceFrequency(Fr);
QueryPerformanceCounter(t1);
ScanDirs("D:\", True);
QueryPerformanceCounter(t2);
ShowMessage(FormatDateTime("hh:nn:ss,z", ((t2-t1)/Fr)/86400));
end;
Сравни два метода и посмотри разницу.
← →
YuRock © (2004-01-06 09:58) [12]> Да, намек на WinAPI. FindFirst, FindNext, FindClose маскируют API шные ф-ции: FindFirstFile, FindNextFile и FindClose. Я считаю что если воспользоваться ими то получится быстрее
Конечно быстрее, ведь FindFirst и FindNext тупо вызывают внутри себя соответственно FindFirstFile и FindNextFile - т.е. меньше лишних операций будет.
Их вообще в дельфях их перекрыли для поддержки
мультиплатформенности (WIN и LINUX), т.ч. если ты пишешь под только винду - используй апишные.
← →
Zergling © (2004-01-06 11:37) [13]NAlexey © (06.01.04 09:42) [11]
1. По поводу WinAPI. Да я смотрел исходники реализации функций приведенных тобой выше. Можно считать, что и замаскерованны они, но думаю особой производительности они не добавят (в данном общем случае это совсем не критично для современных процессоров).
2. А по поводу рекурсии, что ты имел ввиду?
← →
selena (2004-01-06 11:38) [14]Поменял, не то .Да, я тут вообще запутался.
С рекурсией что то, она в голову не лезет,не соображу как она работает.Получается "у ПОПА БЫЛА СОБАКА...".А как вызывать эту процедуру?
← →
NAlexey © (2004-01-06 11:54) [15]Zergling © (06.01.04 11:37) [13]
>в данном общем случае это совсем не критично для современных процессоров
Согласен.
>А по поводу рекурсии, что ты имел ввиду?
Ну не знаю, возможно я не правильно разобрал твой алгоритм. Мне кажется что у тебя сначала перебираются все файлы в текущем каталоге, затем перебираются рекурсивно папки. На мой взгляд надо перебирать последовательно всё, если встретилась папка, то заходим в нее, если это файл, то читаем. Вот это я понимал под рекурсией.
← →
Zergling © (2004-01-06 11:55) [16]selena (06.01.04 11:38) [14]
Чей код имеешь ввиду :)? Уточни!
В моем посте FindFilesInDir("C:\", "*.txt", false);
← →
NAlexey © (2004-01-06 11:56) [17]>selena (06.01.04 11:38) [14]
В чем ты мог запутаться? Вызывай просто:
FindFilesInDir("C:\", "*.*", True{True если искать в подкаталогах, и False если нет});
← →
selena (2004-01-06 12:05) [18]Вообще мне нужно сделать вот что:
Программа должна в определенном каталоге найти все поддиректории зайити в них и распечатать тесктовые файлы которые там найдет.
Я запутался в рекурсивом поиске( к сожалению пока я "сердцем" не пойму эту процедуру она для меня темный лес,пока в голове не укладывается как процедура может вызвать сама себя в процессе своего исполнения,глупо конечно,но ведь все с чего-то начинали), тот код который в самомо начале моя попытка реализовать эту вешь.Может подскажете как это сделать?
← →
Zergling © (2004-01-06 12:08) [19]NAlexey © (06.01.04 11:54) [15]
>> если встретилась папка, то заходим в нее, если это файл, то читаем.
И всеравно я разности невижу. Всеравно в нее потом залазить :). И опять же: если действовать по твоему убеждению, то скорее всего это опять таки некритично. Думаю наэтом наш небольшой спор можно звершить :-)
← →
Zergling © (2004-01-06 12:12) [20]selena (06.01.04 12:05) [18]
А чем примеры ниже неустроили. Код кстати немой :)
Авторстово:
{
Copyright © 1999 by Delphi 5 Developer"s Guide - Xavier Pacheco and Steve Teixeira
}
Очень советую приобрести их двухтомник! CD прилагается.
← →
NAlexey © (2004-01-06 12:14) [21]>Zergling ©
Думаю наэтом наш небольшой спор можно звершить :-)
Согласен:)
>selena (06.01.04 12:05) [18]
Ну тебе же уже привели работающие примеры, почему бы не воспользоваться отладчиком и посмотреть как это работает. Не думаю я что получится проще режить эту проблему без рекурсии.
← →
selena (2004-01-06 13:02) [22]Поставил пример где
Procedure FindFilesInDir(Path, FileMask: String; SearchSubDir:Boolean);
{ Ищет файл по маске в каталоге и его подкаталогах}
Написал
procedure TForm1.Button2Click(Sender: TObject);
begin
FindFilesInDir("C:\watcher\", "*.txt", false);
end;
По коду прошел он ничего не ищет сразу после
while FindResult = 0 do
идет на
if SearchSubDir then
а оттуда сразу на
FindClose(FSearchRec);
Файлы и директории есть.
← →
Zergling © (2004-01-06 13:11) [23]selena (06.01.04 13:02) [22]
А файлы в данной директории фактически существуют?
В имени искомого каталога "C:\watcher\" опечатки нет?
← →
NAlexey © (2004-01-06 13:27) [24]Надо в первой строчке:
Path := AddSlashDir(Path);
← →
selena (2004-01-06 13:33) [25]нашел ,код ищет файлы txt в корне, а не в найденных каталогах.
Как сделать чтобы искал в найденных директориях?
← →
NAlexey © (2004-01-06 13:39) [26]<Как сделать чтобы искал в найденных директориях?>
>Zergling ©
:)) Ужас!
← →
zapped © (2004-01-06 15:20) [27]2selena (06.01.04 13:33) [25]
рекомендую сначала определить для себя, что есть рекурсия
будет проще
Страницы: 1 вся ветка
Текущий архив: 2004.01.16;
Скачать: CL | DM;
Память: 0.54 MB
Время: 0.028 c