|
쏭 님이 쓰신 글 :
: C 드라이브의 모든 DIRECTORY에서
: 그림 파일인 TIF파일을 검색하여
: 삭제를 하는 프로그램을 만들어야 합니다.
: windows의 파일찾기같은 구현을 하려면 어떻게
: 하면 될까요.
:
: 그리고
: winexe를 사용해 dos명령어인 dir을 실행했는데
: 실행된 내용을 파일로 출력하는 방법은 없을까요..?
:
임펠리테리입니다.
먼저 두번째 문제부터. 리다이렉션을 사용하면 됩니다. 리다이렉션은 표준 입출력의 방향을 파일이나 기타 장치로 전환하는 방법입니다. 예를 들면,
c:\> dir *.exe > result.txt
라고 하면, 결과가 result.txt라는 파일에 저장됩니다.
그리고 파일찾기는.. 그냥 FindFirstFile() 과 FindNextFile() 함수를 이용하면 대여섯줄 정도의 코드로 되겠지만, 지금 좀 바빠서요.. 기냥 제가 만들어서 쓰고 있는 컴퍼넌트 하나의 소스를 보여드립니다. 아래 두개의 소스파일을 각각 저장하고 빌더의 컴퍼넌트 메뉴에서 인스톨 컴퍼넌트 해서 설치하세요.
아래는 ImpFindFile.h 헤더파일입니다.
//---------------------------------------------------------------------------
#ifndef ImpFindFileH
#define ImpFindFileH
//---------------------------------------------------------------------------
#include <SysUtils.hpp>
#include <Controls.hpp>
#include <Classes.hpp>
#include <Forms.hpp>
#include <FileCtrl.hpp>
//---------------------------------------------------------------------------
typedef void __fastcall (__closure *TFileFoundEvent)(TObject *Sender, AnsiString &CurrentPath, TSearchRec &F);
typedef void __fastcall (__closure *TDirFoundEvent)(TObject *Sender, AnsiString &CurrentPath, AnsiString &DirName);
class PACKAGE TImpFindFile : public TComponent
{
private:
int FAttr;
int FAborted;
TStringList *FSubDirList;
bool FWorking;
int FFileCount;
int FDirCount;
AnsiString FTargetPath;
AnsiString FFileMask;
TFileType FFileType;
bool FRecursive;
TFileFoundEvent FOnFileFound;
TDirFoundEvent FOnDirFound;
TDirFoundEvent FOnDirExit;
void __fastcall SetTargetPath(AnsiString Value);
protected:
void __fastcall FindFiles(void);
public:
__fastcall TImpFindFile(TComponent* Owner);
__fastcall virtual ~TImpFindFile(void);
void __fastcall Execute(void);
void __fastcall Abort(void);
__property bool Working = {read=FWorking};
__property int FileCount = {read=FFileCount};
__property int DirCount = {read=FDirCount};
__published:
__property AnsiString TargetPath = {read=FTargetPath, write=SetTargetPath};
__property AnsiString FileMask = {read=FFileMask, write=FFileMask};
__property TFileType FileType = {read=FFileType, write=FFileType};
__property bool Recursive = {read=FRecursive, write=FRecursive};
__property TFileFoundEvent OnFileFound = {read=FOnFileFound, write=FOnFileFound};
__property TDirFoundEvent OnDirFound = {read=FOnDirFound, write=FOnDirFound};
__property TDirFoundEvent OnDirExit = {read=FOnDirExit, write=FOnDirExit};
};
//---------------------------------------------------------------------------
#endif
그리고 아래는 ImpFindFile.cpp 소스 파일입니다.
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "ImpFindFile.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
static inline void ValidCtrCheck(TImpFindFile *)
{
new TImpFindFile(NULL);
}
//---------------------------------------------------------------------------
namespace Impfindfile
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TImpFindFile)};
RegisterComponents("Imp", classes, 0);
}
}
//---------------------------------------------------------------------------
__fastcall TImpFindFile::TImpFindFile(TComponent* Owner)
: TComponent(Owner)
{
FAborted = false;
FWorking = false;
FFileCount = 0;
FDirCount = 0;
FTargetPath = "c:\\";
FFileMask = "*.*";
FFileType = TFileType() << ftReadOnly << ftHidden << ftSystem << ftVolumeID << ftDirectory << ftArchive << ftNormal;
FRecursive = true;
FSubDirList = new TStringList;
}
__fastcall TImpFindFile::~TImpFindFile(void)
{
delete FSubDirList;
}
void __fastcall TImpFindFile::SetTargetPath(AnsiString Value)
{
if(DirectoryExists(Value))
FTargetPath = Value;
}
void __fastcall TImpFindFile::Abort(void)
{
FAborted = true;
}
void __fastcall TImpFindFile::Execute(void)
{
FFileCount = 0;
FDirCount = 0;
AnsiString CurrentPath = GetCurrentDir();
if(SetCurrentDir(TargetPath)==false)
return;
int Attributes[7] = {faReadOnly, faHidden, faSysFile, faVolumeID, faDirectory, faArchive, 0};
int AttrWord = DDL_READWRITE;
for(int i=ftReadOnly; i<=ftArchive; i++)
if(FileType.Contains((TFileAttr)i))
AttrWord = AttrWord | Attributes[i];
FindFiles();
FAborted = false;
SetCurrentDir(CurrentPath);
}
void __fastcall TImpFindFile::FindFiles(void)
{
TSearchRec Sr;
AnsiString CurrentPath = GetCurrentDir();
if(FindFirst(FFileMask, FAttr, Sr)==0)
{
do
{
FFileCount++;
if(FOnFileFound!=NULL) FOnFileFound(this, CurrentPath, Sr);
Application->ProcessMessages();
}
while(FindNext(Sr)==0 && !FAborted);
FindClose(Sr);
if(FAborted) return;
}
if(FRecursive && FindFirst("*.*", faDirectory, Sr)==0)
{
FSubDirList->Clear();
do
if((Sr.Attr & faDirectory) == faDirectory && Sr.Name[1] != '.')
FSubDirList->Add(Sr.Name);
while(FindNext(Sr)==0 && !FAborted);
FindClose(Sr);
if(FAborted) return;
for(int i=0; i<FSubDirList->Count; i++)
{
FDirCount++;
if(FOnDirFound!=NULL) FOnDirFound(this, CurrentPath, FSubDirList->Strings[i]);
SetCurrentDir(FSubDirList->Strings[i]);
FindFiles();
SetCurrentDir(CurrentPath);
if(FOnDirExit!=NULL) FOnDirExit(this, CurrentPath, FSubDirList->Strings[i]);
}
}
}
사용법은 간단합니다. *.tif 를 찾으려면 FileMask 프로퍼티에 *tif라고 넣고, 발견되는 대로 몽땅 지우려면, OnFileFound 이벤트 핸들러를 만들어서 넘어온 인자인 CurrentPath와 F를 조합해서 파일명을 만든 후 DeleteFile() 함수로 지우면 됩니다. 다음과 같이 말이죠.
void __fastcall TForm1::ImpFindFile1FileFound(TObject *Sender,
AnsiString &CurrentPath, TSearchRec &F)
{
DeleteFile(CurrentPath + F.Name);
}
그럼 참고하시길...
|