Поиск Файлов, IsDirectory()
Реализовать на С++ API функциям аналог класса CFileFind из MFC.
Что я и сделал!
Но вот возникла одна нестыковка - определить, является ли найденный файл папкой.
Потому как сравнение с атрибутом FILE_ATTRIBUTE_DIRECTORY иногда дает отрицательный результат, даже на папку(CFileFind работает правильно). Например [D:\Program Files] он за папку не считает.
MFC использовать нельзя.
CLR использовать нельзя(я использовал только для вывода Unicode строк)
Код:
Код:
#include <windows.h>
#include <iostream>
#include <atlstr.h>
#include <stack>
#using <mscorlib.dll>
using namespace std;
using namespace System;
#define C CString
// Обеспечивает учет ссылок
class HANDLEFIND
{
protected:
HANDLE H;
int* count;
public:
inline HANDLEFIND()
{
this->count=NULL;
this->H=NULL;
}
inline explicit HANDLEFIND(const HANDLE &h)
{
this->H=h;
this->count = new int();
*this->count = 1;
return;
}
inline explicit HANDLEFIND(const HANDLEFIND &hCom)
{
this->count = hCom.count;
*hCom.count+=1;
this->H = hCom.H;
return;
}
~HANDLEFIND()
{
this->Release();
}
public:
inline void AddRef()
{
*(this->count)+=1;
return;
}
inline void Release()
{
if(this->H!=NULL )
{
*this->count -= 1;
if(*this->count==0)
{
FindClose(this->H);
delete count;
//cout<<"->delete"<<endl;
}
}
return;
}
inline int GetCount()
{
return *this->count;
}
inline HANDLE GetHandle()
{
return this->H;
}
public:
inline void operator = (const HANDLE &h)
{
this->Release();
this->H=h;
this->count = new int();
*this->count = 1;
return;
}
inline void operator = (const HANDLEFIND &hCom)
{
this->Release();
this->count = hCom.count;
this->H = hCom.H;
this->AddRef();
return;
}
};
// Ищет файл в директории
class WinFileFind
{
public:
WIN32_FIND_DATA FileInfo;
HANDLEFIND hFind;
CString Root;
public:
WinFileFind()
{
return;
}
~WinFileFind()
{
return;
}
//
void Close(){ hFind.Release();}
bool FindFirst(CString Where, CString Mask)
{
Root = Where;
hFind = FindFirstFile(this->Root+Mask,&this->FileInfo);
return (hFind.GetHandle() != INVALID_HANDLE_VALUE);
}
bool FindNext()
{
return FindNextFile(this->hFind.GetHandle(),&this->FileInfo);
}
//
bool IsReadOnly() { return this->FileInfo.dwFileAttributes == FILE_ATTRIBUTE_READONLY; }
bool IsHidden() { return this->FileInfo.dwFileAttributes == FILE_ATTRIBUTE_HIDDEN; }
bool IsSystem() { return this->FileInfo.dwFileAttributes == FILE_ATTRIBUTE_SYSTEM; }
bool IsDirectory() { return this->FileInfo.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY; }
bool IsArchive() { return this->FileInfo.dwFileAttributes == FILE_ATTRIBUTE_ARCHIVE; }
bool IsNormal() { return this->FileInfo.dwFileAttributes == FILE_ATTRIBUTE_NORMAL; }
bool IsTemporary() { return this->FileInfo.dwFileAttributes == FILE_ATTRIBUTE_TEMPORARY; }
bool IsCompressed() { return this->FileInfo.dwFileAttributes == FILE_ATTRIBUTE_COMPRESSED; }
bool IsDots() { return (this->FileInfo.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)?((C)this->FileInfo.cFileName == L".." || (C)this->FileInfo.cFileName == L"."):false;}
//
CString GetFileName()
{
return this->FileInfo.cFileName;
}
CString GetFilePath()
{
return this->Root + this->FileInfo.cFileName;
}
CString GetRoot()
{
return this->Root;
}
CString GetFileTitle()
{
CString Title = FileInfo.cFileName;
int index;
if((index = Title.ReverseFind('.'))>0) return Title.Left(index);
else return Title;
}
CString GetExtension()
{
CString Title = FileInfo.cFileName;
int index;
if((index = Title.ReverseFind('.'))>0) return Title.Right(Title.GetLength()-index-1);
else return L"";
}
//
WinFileFind(const WinFileFind &Find)
{
this->FileInfo = Find.FileInfo;
this->hFind = Find.hFind;
this->Root = Find.Root;
}
};
//////////////////////////
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
WinFileFind F;
F.FindFirst("D:\\","*");
Console::WriteLine(gcnew String(F.GetFilePath()));
Console::WriteLine(F.IsDirectory());
while(F.FindNext())
{
Console::WriteLine(gcnew String(F.GetFilePath()));
Console::WriteLine(F.IsDirectory());
}
cout<<"END"<<endl;
}
#include <iostream>
#include <atlstr.h>
#include <stack>
#using <mscorlib.dll>
using namespace std;
using namespace System;
#define C CString
// Обеспечивает учет ссылок
class HANDLEFIND
{
protected:
HANDLE H;
int* count;
public:
inline HANDLEFIND()
{
this->count=NULL;
this->H=NULL;
}
inline explicit HANDLEFIND(const HANDLE &h)
{
this->H=h;
this->count = new int();
*this->count = 1;
return;
}
inline explicit HANDLEFIND(const HANDLEFIND &hCom)
{
this->count = hCom.count;
*hCom.count+=1;
this->H = hCom.H;
return;
}
~HANDLEFIND()
{
this->Release();
}
public:
inline void AddRef()
{
*(this->count)+=1;
return;
}
inline void Release()
{
if(this->H!=NULL )
{
*this->count -= 1;
if(*this->count==0)
{
FindClose(this->H);
delete count;
//cout<<"->delete"<<endl;
}
}
return;
}
inline int GetCount()
{
return *this->count;
}
inline HANDLE GetHandle()
{
return this->H;
}
public:
inline void operator = (const HANDLE &h)
{
this->Release();
this->H=h;
this->count = new int();
*this->count = 1;
return;
}
inline void operator = (const HANDLEFIND &hCom)
{
this->Release();
this->count = hCom.count;
this->H = hCom.H;
this->AddRef();
return;
}
};
// Ищет файл в директории
class WinFileFind
{
public:
WIN32_FIND_DATA FileInfo;
HANDLEFIND hFind;
CString Root;
public:
WinFileFind()
{
return;
}
~WinFileFind()
{
return;
}
//
void Close(){ hFind.Release();}
bool FindFirst(CString Where, CString Mask)
{
Root = Where;
hFind = FindFirstFile(this->Root+Mask,&this->FileInfo);
return (hFind.GetHandle() != INVALID_HANDLE_VALUE);
}
bool FindNext()
{
return FindNextFile(this->hFind.GetHandle(),&this->FileInfo);
}
//
bool IsReadOnly() { return this->FileInfo.dwFileAttributes == FILE_ATTRIBUTE_READONLY; }
bool IsHidden() { return this->FileInfo.dwFileAttributes == FILE_ATTRIBUTE_HIDDEN; }
bool IsSystem() { return this->FileInfo.dwFileAttributes == FILE_ATTRIBUTE_SYSTEM; }
bool IsDirectory() { return this->FileInfo.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY; }
bool IsArchive() { return this->FileInfo.dwFileAttributes == FILE_ATTRIBUTE_ARCHIVE; }
bool IsNormal() { return this->FileInfo.dwFileAttributes == FILE_ATTRIBUTE_NORMAL; }
bool IsTemporary() { return this->FileInfo.dwFileAttributes == FILE_ATTRIBUTE_TEMPORARY; }
bool IsCompressed() { return this->FileInfo.dwFileAttributes == FILE_ATTRIBUTE_COMPRESSED; }
bool IsDots() { return (this->FileInfo.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)?((C)this->FileInfo.cFileName == L".." || (C)this->FileInfo.cFileName == L"."):false;}
//
CString GetFileName()
{
return this->FileInfo.cFileName;
}
CString GetFilePath()
{
return this->Root + this->FileInfo.cFileName;
}
CString GetRoot()
{
return this->Root;
}
CString GetFileTitle()
{
CString Title = FileInfo.cFileName;
int index;
if((index = Title.ReverseFind('.'))>0) return Title.Left(index);
else return Title;
}
CString GetExtension()
{
CString Title = FileInfo.cFileName;
int index;
if((index = Title.ReverseFind('.'))>0) return Title.Right(Title.GetLength()-index-1);
else return L"";
}
//
WinFileFind(const WinFileFind &Find)
{
this->FileInfo = Find.FileInfo;
this->hFind = Find.hFind;
this->Root = Find.Root;
}
};
//////////////////////////
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
WinFileFind F;
F.FindFirst("D:\\","*");
Console::WriteLine(gcnew String(F.GetFilePath()));
Console::WriteLine(F.IsDirectory());
while(F.FindNext())
{
Console::WriteLine(gcnew String(F.GetFilePath()));
Console::WriteLine(F.IsDirectory());
}
cout<<"END"<<endl;
}
У меня в принципе есть идея пробовать искать файл ".." в каждом файле без расширения, но может кто знает более простое решение?
PS. Идея не сработала. Каждый файл без расширения он проименовал как папку!
И еще если можно, есть ли какой-нибудь атрибут отличающий директории "???\.." "???\." от прочих
Надо было поставить:
bool IsDirectory() { return this->FileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; }
, а не:
bool IsDirectory() { return this->FileInfo.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY; }
Остается вопрос: Есть ли флаг для директорий "." и "..", отличающий их от прочих директорий!!!
Цитата: sigmov
У меня в принципе есть идея пробовать искать файл ".." в каждом файле без расширения
Во-первых,это не файл,а папка;во-вторых,как это–"в каждом файле без расширения"?Файлы в файлах искать нельзя!:D
Лучше,конечно,было бы с использованием WinAPI…но если нельзя,то просто надо сравнивать имя очередной найденной папки с "." и ".."
А флага никакого для этих папок нет
bool IsDots() { return (this->FileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)?(*(wchar_t*)&this->FileInfo.cFileName == L'.'):false; }
Цитата: sigmov
bool IsDots() { return (this->FileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)?(*(wchar_t*)&this->FileInfo.cFileName == L'.'):false; }
Но здесь вы только "." проверяете, а где ".."? И сравнение строк через == не совсем гуд имхо.