Форум — Ответы     (  К темам )
 ?  Dr.Phoenix: помогите найти ошибку... (29-03-2003 16:30:35)
FindFirstFile находит директрории "." и "..", т.к. мне они не нужны, то я делаю так:

void SearchFunction(AnsiString Location)
{
Location+="\*";
WIN32_FIND_DATA FileInfo;
HANDLE Search = FindFirstFile(Location.c_str(),&FileInfo);
if(Search==INVALID_HANDLE_VALUE)
{MessageBox(NULL,"error","error",MB_OK|MB_ICONERROR);return;}

if(FileInfo.dwFileAttributes==FILE_ATTRIBUTE_DIRECTORY)
if((FileInfo.cFileName!=".")&&(FileInfo.cFileName!="..")){
Form1->Memo1->Lines->Add(FileInfo.cFileName);
SearchFunction(Form1->Path->Text+FileInfo.cFileName);
}

while(FindNextFile(Search,&FileInfo))
if(FileInfo.dwFileAttributes==FILE_ATTRIBUTE_DIRECTORY)
if((FileInfo.cFileName!=".")&&(FileInfo.cFileName!="..")){
Form1->Memo1->Lines->Add(FileInfo.cFileName);
SearchFunction(Form1->Path->Text+FileInfo.cFileName);
}
}

Проблема в том, что если имя найденного каталога ".", то условие почему-то выполняется :( Второй час на него смотрю и не могу понять в чем причина.
Наверно надо было поспать этой ночью :) В общем хелп!
 Павел (29-03-2003 18:22:36)
А что такое Path ? (Form1->Path->...)
 Павел (29-03-2003 18:57:01)
// Я так понял, что Path — это компонент типа TEdit
// Попробуйте вот так:

void SearchFunction(AnsiString Location)
{
Location = Location + "\*";
Form1->Memo2->Lines->Add(Location);
WIN32_FIND_DATA FileInfo;
HANDLE Search = FindFirstFile(Location.c_str(),&FileInfo);
if(Search==INVALID_HANDLE_VALUE)
{MessageBox(NULL,"error","error",MB_OK|MB_ICONERROR); return;}

while(FindNextFile(Search,&FileInfo)){
if(FileInfo.dwFileAttributes==FILE_ATTRIBUTE_DIRECTORY &&
FileInfo.cFileName != "." && FileInfo.cFileName != ".."){
Form1->Memo1->Lines->Add(FileInfo.cFileName);
SearchFunction(Form1->Path->Text+FileInfo.cFileName);
}
}
}


//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
Form1->Path->Text = "c:\\";
SearchFunction(Form1->Path->Text);
}
//---------------------------------------------------------------------------

// у меня работает
 Dr.Phoenix (29-03-2003 21:55:34)
Если

void __fastcall TForm1::Button2Click(TObject *Sender)
{
Form1->Path->Text = "c:\\";
SearchFunction(Form1->Path->Text);
}
, то работает, а если

void __fastcall TForm1::Button2Click(TObject *Sender)
{
Form1->Path->Text = "c:\\windows\\";
SearchFunction(Form1->Path->Text);
}
, то Project raised exception class EStackOverflow with message 'Stack overflow'. Process stopped. Use Step Run to continue.
В корне и у меня работало, тк там нету '.' и '..'
Как сделать, чтою работало и в папках?
 Dr.Phoenix (29-03-2003 21:59:26)
2 Павел
и SearchFunction должна вызываться рекурсивно, а этого не происходит :(
 Павел (30-03-2003 12:27:47)
Функция и работает рекурсивно.
Кажется я понял с чем была проблема (с . или ..)
Посмотрите тип FileInfo.cFileName — он char[260], а не AnsiString,
кажется проблема была в этом.

Посмотрите вот так:
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
Path->Text = "c:\\";
}
//---------------------------------------------------------------------------
void SearchFunction(AnsiString Location)
{
Location = Location + "\*";
Form1->Memo2->Lines->Add(Location);
WIN32_FIND_DATA FileInfo;
HANDLE Search = FindFirstFile(Location.c_str(),&FileInfo);
if(Search==INVALID_HANDLE_VALUE)
{MessageBox(NULL,"error","error",MB_OK|MB_ICONERROR); return;}

while(FindNextFile(Search,&FileInfo)){
Form1->Memo3->Lines->Add(FileInfo.cFileName);
AnsiString fn = FileInfo.cFileName;
if(FileInfo.dwFileAttributes==FILE_ATTRIBUTE_DIRECTORY && fn != "." && fn != "..")
{
Form1->Memo1->Lines->Add(fn);
SearchFunction(Form1->Path->Text + fn);
}
}
}

void __fastcall TForm1::Button1Click(TObject *Sender)
{
Form1->Path->Text = Path->Text;
SearchFunction(Form1->Path->Text);
}
//---------------------------------------------------------------------------

// попробуйте у себя добавить:
// AnsiString fn = FileInfo.cFileName;
// и все сравнения и присвоения делать с fn
 Dr.Phoenix (31-03-2003 02:19:33)
То, что было нужно, получилось вот так:
//-------------------------------------------------
void SearchFunction(AnsiString Location)
{
AnsiString PATH=Location;
Location = Location + "*";
WIN32_FIND_DATA FileInfo;
HANDLE Search = FindFirstFile(Location.c_str(),&FileInfo);
if(Search==INVALID_HANDLE_VALUE)
{MessageBox(NULL,"error",":-(",MB_OK|MB_ICONERROR); return;}

AnsiString fz = FileInfo.cFileName;
if(FileInfo.dwFileAttributes==FILE_ATTRIBUTE_DIRECTORY && fz != "." && fz != "..")
{
AnsiString tmp;
fz=strcat(FileInfo.cFileName,"\\");
tmp=PATH + fz;
Form1->Memo1->Lines->Add(tmp);
SearchFunction(PATH + fz);
}

while(FindNextFile(Search,&FileInfo)){
AnsiString fn = FileInfo.cFileName;
if(FileInfo.dwFileAttributes==FILE_ATTRIBUTE_DIRECTORY && fn != "." && fn != "..")
{
AnsiString tmp;
fn=strcat(FileInfo.cFileName,"\\");
tmp=PATH + fn;
Form1->Memo1->Lines->Add(tmp);
SearchFunction(PATH + fn);
}
}

//------------------------------------

2 Павел
пасиба за оказанный хелп :)
 Dr.Phoenix (31-03-2003 03:31:07)
Еще не все :)
Почему криво работает след. функция:
(Идея такая: параметр Location — путь к существующей директории с файлами, напр C:\Windows\, DestPath — путь новой директории, напр C:\zzz\, ф-ция должна найти все файлы и папки в C:\Windows и создать такую же структуру файлов и папок в C:\zzz\. Вроде как работает, но если включить св-ва папки, то можно увидеть,что в созданной папке оказывается немного меньше файлов и папок, чем в исходной. Почему так происходит?)
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
void SearchFunction(AnsiString Location,AnsiString DestPath)
{
CreateDir(DestPath);
AnsiString PATH=Location;
Location = Location + "*";
WIN32_FIND_DATA FileInfo;
HANDLE Search = FindFirstFile(Location.c_str(),&FileInfo);
if(Search==INVALID_HANDLE_VALUE)
{MessageBox(NULL,":-(",":-(",MB_OK|MB_ICONERROR); return;}

AnsiString fz = FileInfo.cFileName;
if(FileInfo.dwFileAttributes==FILE_ATTRIBUTE_DIRECTORY && fz != "." && fz != "..")
{
AnsiString tmp;
fz=strcat(FileInfo.cFileName,"\\");
CreateDir(DestPath+fz);
tmp=PATH + fz;
Form1->FileList->Lines->Add(tmp);
SearchFunction(PATH + fz,DestPath+fz);
} else
{Form1->FileList->Lines->Add(PATH+fz); //FileList — компонент типа TMemo
ofstream file;
AnsiString ccc,vvv;
ccc=FileInfo.cFileName;
vvv=DestPath+ccc;
file.open(vvv.c_str(),ios_base::out);
file.close(); }


while(FindNextFile(Search,&FileInfo)){
AnsiString fn = FileInfo.cFileName;
if(FileInfo.dwFileAttributes==FILE_ATTRIBUTE_DIRECTORY && fn != "." && fn != "..")
{
AnsiString tmp;
fn=strcat(FileInfo.cFileName,"\\");
CreateDir(DestPath+fn);
tmp=PATH + fn;
Form1->FileList->Lines->Add(tmp);
SearchFunction(PATH + fn,DestPath+fn);
}
else
{Form1->FileList->Lines->Add(PATH+fn);
ofstream file;
AnsiString zzz,xxx;
zzz=FileInfo.cFileName;
xxx=DestPath+zzz;
file.open(xxx.c_str(),ios_base::out);
file.close(); }
}
}
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
 Георгий (31-03-2003 09:06:02)
Может скрытые/системные файлы/какалоги не копируются?
 Dr.Phoenix (31-03-2003 22:20:05)
Да... Если у папки стоят какие-нить атрибуты типа Hidden или Archive, то за папку она уже не считается :)