ऐसा लगता है कि मुझे यहां बहुत सारे कोड को रेखांकित करना था। मैं सोच रहा हूँ अगर यह इस तरह एक हेडर फाइल में पूरी तरह से छोड़ने के लिए बुरा डिजाइन अभ्यास है:क्या हेडर केवल लाइब्रेरी के लिए यह बहुत अधिक कोड है?
#include <list>
#include <string>
#include <boost/noncopyable.hpp>
#include <boost/make_shared.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <Windows.h>
#include "../Exception.hpp"
namespace WindowsAPI { namespace FileSystem {
class NonRecursiveEnumeration;
class RecursiveEnumeration;
struct AllResults;
struct FilesOnly;
template <typename Filter_T = AllResults, typename Recurse_T = NonRecursiveEnumeration>
class DirectoryIterator;
template <typename Recurse_T>
struct FileData;
class NonRecursiveEnumeration : public boost::noncopyable
{
WIN32_FIND_DATAW currentData;
HANDLE hFind;
std::wstring root;
public:
NonRecursiveEnumeration() : hFind(INVALID_HANDLE_VALUE) {
};
NonRecursiveEnumeration(const std::wstring& pathSpec) {
std::wstring::const_iterator lastSlash =
std::find(pathSpec.rbegin(), pathSpec.rend(), L'\\').base();
if (lastSlash != pathSpec.end())
root.assign(pathSpec.begin(), lastSlash);
hFind = FindFirstFileW(pathSpec.c_str(), ¤tData);
if (hFind == INVALID_HANDLE_VALUE)
WindowsApiException::ThrowFromLastError();
while (!wcscmp(currentData.cFileName, L".") || !wcscmp(currentData.cFileName, L"..")) {
increment();
}
};
void increment() {
BOOL success =
FindNextFile(hFind, ¤tData);
if (success)
return;
DWORD error = GetLastError();
if (error == ERROR_NO_MORE_FILES) {
FindClose(hFind);
hFind = INVALID_HANDLE_VALUE;
} else {
WindowsApiException::Throw(error);
}
};
~NonRecursiveEnumeration() {
if (hFind != INVALID_HANDLE_VALUE)
FindClose(hFind);
};
bool equal(const NonRecursiveEnumeration& other) const {
if (this == &other)
return true;
return hFind == other.hFind;
};
const std::wstring& GetPathRoot() const {
return root;
};
const WIN32_FIND_DATAW& GetCurrentFindData() const {
return currentData;
};
};
//Not implemented yet
class RecursiveEnumeration : public boost::noncopyable
{
};
template <typename Recurse_T>
struct FileData //Serves as a proxy to the WIN32_FIND_DATA struture inside the iterator.
{
const Recurse_T* impl;
template <typename Filter_T, typename Recurse_T>
FileData(const DirectoryIterator<Filter_T, Recurse_T>* parent) : impl(parent->impl.get()) {};
DWORD GetAttributes() const {
return impl->GetCurrentFindData().dwFileAttributes;
};
bool IsDirectory() const {
return (GetAttributes() & FILE_ATTRIBUTE_DIRECTORY) != 0;
};
bool IsFile() const {
return !IsDirectory();
};
bool IsArchive() const {
return (GetAttributes() & FILE_ATTRIBUTE_ARCHIVE) != 0;
};
bool IsReadOnly() const {
return (GetAttributes() & FILE_ATTRIBUTE_READONLY) != 0;
};
unsigned __int64 GetSize() const {
ULARGE_INTEGER intValue;
intValue.LowPart = impl.GetCurrentFindData().nFileSizeLow;
intValue.HighPart = impl.GetCurrentFindData().nFileSizeHigh;
return intValue.QuadPart;
};
std::wstring GetFolderPath() const {
return impl->GetPathRoot();
};
std::wstring GetFileName() const {
return impl->GetCurrentFindData().cFileName;
};
std::wstring GetFullFileName() const {
return GetFolderPath() + GetFileName();
};
std::wstring GetShortFileName() const {
return impl->GetCurrentFindData().cAlternateFileName;
};
FILETIME GetCreationTime() const {
return impl->GetCurrentFindData().ftCreationTime;
};
FILETIME GetLastAccessTime() const {
return impl->GetCurrentFindData().ftLastAccessTime;
};
FILETIME GetLastWriteTime() const {
return impl->GetCurrentFindData().ftLastWriteTime;
};
};
struct AllResults
{
template <typename Recurse_T>
bool operator()(const FileData<Recurse_T>&) {
return true;
};
};
struct FilesOnly
{
template <typename Recurse_T>
bool operator()(const FileData<Recurse_T>& arg) {
return arg.IsFile();
};
};
#pragma warning(push)
#pragma warning(disable: 4355)
template <typename Filter_T, typename Recurse_T>
class DirectoryIterator : public boost::iterator_facade<DirectoryIterator<Filter_T>, const FileData<Recurse_T>, std::input_iterator_tag>
{
friend class boost::iterator_core_access;
boost::shared_ptr<Recurse_T> impl;
FileData<Recurse_T> derefData;
Filter_T filter;
void increment() {
do {
impl->increment();
} while (! filter(derefData));
};
bool equal(const DirectoryIterator& other) const {
return impl->equal(*other.impl);
};
const FileData<Recurse_T>& dereference() const {
return derefData;
};
public:
typedef FileData<Recurse_T> DataType;
friend struct DataType;
DirectoryIterator(Filter_T functor = Filter_T()) :
impl(boost::make_shared<Recurse_T>()),
derefData(this),
filter(functor) {
};
explicit DirectoryIterator(const std::wstring& pathSpec, Filter_T functor = Filter_T()) :
impl(boost::make_shared<Recurse_T>(pathSpec)),
derefData(this),
filter(functor) {
};
};
#pragma warning(pop)
}}
यदि यह केवल शीर्षलेख है, तो मुझे लगता है कि आपकी सबसे अच्छी शर्त इसे कई फ़ाइलों में विभाजित करना है। "विस्तार/DirectoryIterator.hpp", आदि की तरह, कम से कम यह एक फ़ाइल में निहित नहीं है। बूस्ट करता है यही है। वैसे, बूस्ट में एक फाइल सिस्टम लाइब्रेरी है, बस अगर आपको पता नहीं था। – GManNickG
@GMan: +1। हां, बूस्ट में एक फाइल सिस्टम लाइब्रेरी है, लेकिन इसे क्रॉस प्लेटफार्म संगतता के लिए डिज़ाइन किया गया है, जिसके लिए मुझे पसंद नहीं होने वाले वर्म्स का पूरा खुलना आवश्यक है (उदाहरण के लिए इसका अपना पथ प्रोसेसर है)। इसके साथ मुझे लगता है कि मैं क्लाइंट कोड स्पष्ट कर सकता हूं जो क्रॉस प्लेटफार्म पोर्टेबिलिटी की परवाह नहीं करता है। –
यह देखने में अच्छा लगा कि आप का अच्छा उपयोग हो रहा है: http://stackoverflow.com/questions/2531874/how-might-i-wrap-the-findxfile-style-apis-to-the-stl-style-iterator -पटर-इन-सी –