Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 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
14-49681
Goblin
2003-12-26 12:15
2004.01.16
В паскале нет функции копирования файлов?


3-49446
www
2003-12-18 11:56
2004.01.16
TUpdateSQL для 2-х таблиц


3-49416
}|{yk
2003-12-05 14:50
2004.01.16
MySQL и dbExpress


14-49762
PVOzerski
2003-12-24 10:23
2004.01.16
Федорино горе, или о забавных нелепостях в названиях программ


1-49608
Dimmu Borgir
2004-01-04 14:05
2004.01.16
Форму в компонент